Spaces:
Sleeping
Sleeping
Captain Ezio
commited on
Commit
·
b48df3a
1
Parent(s):
f192ee1
fixes
Browse files- .gitignore +1 -0
- Powers/__init__.py +7 -1
- Powers/bot_class.py +0 -2
- Powers/plugins/clean_db.py +0 -68
- Powers/plugins/dev.py +0 -18
- Powers/plugins/flood.py +8 -5
- Powers/plugins/greetings.py +2 -2
- Powers/plugins/scheduled_jobs.py +2 -66
- Powers/plugins/start.py +2 -3
- Powers/plugins/web_con.py +15 -15
- Powers/utils/sticker_help.py +2 -1
- Powers/utils/web_helpers.py +87 -22
- Powers/utils/web_scrapper.py +10 -7
- Powers/vars.py +2 -2
- README.md +4 -2
.gitignore
CHANGED
@@ -7,6 +7,7 @@ postgres-data/
|
|
7 |
logs/
|
8 |
Powers/local_vars.py
|
9 |
.idea/
|
|
|
10 |
|
11 |
# Byte-compiled / optimized / DLL files
|
12 |
__pycache__/
|
|
|
7 |
logs/
|
8 |
Powers/local_vars.py
|
9 |
.idea/
|
10 |
+
scrapped/
|
11 |
|
12 |
# Byte-compiled / optimized / DLL files
|
13 |
__pycache__/
|
Powers/__init__.py
CHANGED
@@ -119,7 +119,7 @@ API_ID = Config.API_ID
|
|
119 |
API_HASH = Config.API_HASH
|
120 |
|
121 |
# General Config
|
122 |
-
MESSAGE_DUMP = Config.MESSAGE_DUMP
|
123 |
SUPPORT_GROUP = Config.SUPPORT_GROUP
|
124 |
SUPPORT_CHANNEL = Config.SUPPORT_CHANNEL
|
125 |
|
@@ -151,6 +151,12 @@ else:
|
|
151 |
shutil.rmtree(youtube_dir)
|
152 |
mkdir(youtube_dir)
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
scheduler = AsyncIOScheduler(timezone=TIME_ZONE)
|
155 |
|
156 |
|
|
|
119 |
API_HASH = Config.API_HASH
|
120 |
|
121 |
# General Config
|
122 |
+
MESSAGE_DUMP = Config.MESSAGE_DUMP if Config.MESSAGE_DUMP else Config.OWNER_ID
|
123 |
SUPPORT_GROUP = Config.SUPPORT_GROUP
|
124 |
SUPPORT_CHANNEL = Config.SUPPORT_CHANNEL
|
125 |
|
|
|
151 |
shutil.rmtree(youtube_dir)
|
152 |
mkdir(youtube_dir)
|
153 |
|
154 |
+
scrap_dir = "./scrapped/"
|
155 |
+
if not path.isdir(scrap_dir):
|
156 |
+
mkdir(scrap_dir)
|
157 |
+
else:
|
158 |
+
shutil.rmtree(scrap_dir)
|
159 |
+
mkdir(scrap_dir)
|
160 |
scheduler = AsyncIOScheduler(timezone=TIME_ZONE)
|
161 |
|
162 |
|
Powers/bot_class.py
CHANGED
@@ -70,8 +70,6 @@ class Gojo(Client):
|
|
70 |
await load_support_users()
|
71 |
await cache_support()
|
72 |
LOGGER.info(f"Plugins Loaded: {cmd_list}")
|
73 |
-
scheduler.add_job(clean_my_db, 'cron', [
|
74 |
-
self], hour=3, minute=0, second=0)
|
75 |
if BDB_URI:
|
76 |
scheduler.add_job(send_wishish, 'cron', [
|
77 |
self], hour=0, minute=0, second=0)
|
|
|
70 |
await load_support_users()
|
71 |
await cache_support()
|
72 |
LOGGER.info(f"Plugins Loaded: {cmd_list}")
|
|
|
|
|
73 |
if BDB_URI:
|
74 |
scheduler.add_job(send_wishish, 'cron', [
|
75 |
self], hour=0, minute=0, second=0)
|
Powers/plugins/clean_db.py
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
import time
|
2 |
-
from traceback import format_exc
|
3 |
-
|
4 |
-
from pyrogram.enums import ChatMemberStatus as CMS
|
5 |
-
from pyrogram.errors import UserNotParticipant
|
6 |
-
|
7 |
-
from Powers import LOGGER, MESSAGE_DUMP
|
8 |
-
from Powers.bot_class import Gojo
|
9 |
-
from Powers.database.approve_db import Approve
|
10 |
-
from Powers.database.blacklist_db import Blacklist
|
11 |
-
from Powers.database.chats_db import Chats
|
12 |
-
from Powers.database.disable_db import Disabling
|
13 |
-
from Powers.database.filters_db import Filters
|
14 |
-
from Powers.database.flood_db import Floods
|
15 |
-
from Powers.database.greetings_db import Greetings
|
16 |
-
from Powers.database.notes_db import Notes, NotesSettings
|
17 |
-
from Powers.database.pins_db import Pins
|
18 |
-
from Powers.database.reporting_db import Reporting
|
19 |
-
# from Powers.database.users_db import Users
|
20 |
-
from Powers.database.warns_db import Warns, WarnSettings
|
21 |
-
|
22 |
-
|
23 |
-
async def clean_my_db(c: Gojo, is_cmd=False, id=None):
|
24 |
-
to_clean = list()
|
25 |
-
chats_list = Chats.list_chats_by_id()
|
26 |
-
to_clean.clear()
|
27 |
-
start = time.time()
|
28 |
-
for chats in chats_list:
|
29 |
-
try:
|
30 |
-
stat = await c.get_chat_member(chat_id=chats, user_id=c.me.id)
|
31 |
-
if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]:
|
32 |
-
to_clean.append(chats)
|
33 |
-
except UserNotParticipant:
|
34 |
-
to_clean.append(chats)
|
35 |
-
except Exception as e:
|
36 |
-
LOGGER.error(e)
|
37 |
-
LOGGER.error(format_exc())
|
38 |
-
if not is_cmd:
|
39 |
-
return e
|
40 |
-
else:
|
41 |
-
to_clean.append(chats)
|
42 |
-
for i in to_clean:
|
43 |
-
Approve(i).clean_approve()
|
44 |
-
Blacklist(i).clean_blacklist()
|
45 |
-
Chats.remove_chat(i)
|
46 |
-
Disabling(i).clean_disable()
|
47 |
-
Filters().rm_all_filters(i)
|
48 |
-
Floods().rm_flood(i)
|
49 |
-
Greetings(i).clean_greetings()
|
50 |
-
Notes().rm_all_notes(i)
|
51 |
-
NotesSettings().clean_notes(i)
|
52 |
-
Pins(i).clean_pins()
|
53 |
-
Reporting(i).clean_reporting()
|
54 |
-
Warns(i).clean_warn()
|
55 |
-
WarnSettings(i).clean_warns()
|
56 |
-
x = len(to_clean)
|
57 |
-
txt = f"#INFO\n\nCleaned db:\nTotal chats removed: {x}"
|
58 |
-
to_clean.clear()
|
59 |
-
nums = time.time()-start
|
60 |
-
if is_cmd:
|
61 |
-
txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}"
|
62 |
-
txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process"
|
63 |
-
await c.send_message(chat_id=MESSAGE_DUMP, text=txt)
|
64 |
-
return txt
|
65 |
-
else:
|
66 |
-
txt += f"\nClean type: Auto\n\tTook {round(nums,2)} seconds to complete the process"
|
67 |
-
await c.send_message(chat_id=MESSAGE_DUMP, text=txt)
|
68 |
-
return txt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Powers/plugins/dev.py
CHANGED
@@ -24,7 +24,6 @@ from Powers.database import MongoDB
|
|
24 |
from Powers.database.chats_db import Chats
|
25 |
from Powers.database.support_db import SUPPORTS
|
26 |
from Powers.database.users_db import Users
|
27 |
-
from Powers.plugins.scheduled_jobs import clean_my_db
|
28 |
from Powers.utils.clean_file import remove_markdown_and_html
|
29 |
from Powers.utils.custom_filters import command
|
30 |
from Powers.utils.extract_user import extract_user
|
@@ -738,23 +737,6 @@ async def forward_type_broadcast(c: Gojo, m: Message):
|
|
738 |
return
|
739 |
|
740 |
|
741 |
-
@Gojo.on_message(command(["cleandb","cleandatabase"],sudo_cmd=True))
|
742 |
-
async def cleeeen(c:Gojo,m:Message):
|
743 |
-
x = await m.reply_text("Cleaning the database...")
|
744 |
-
try:
|
745 |
-
z = await clean_my_db(c,True,m.from_user.id)
|
746 |
-
try:
|
747 |
-
await x.delete()
|
748 |
-
except Exception:
|
749 |
-
pass
|
750 |
-
await m.reply_text(z)
|
751 |
-
return
|
752 |
-
except Exception as e:
|
753 |
-
await m.reply_text(e)
|
754 |
-
await x.delete()
|
755 |
-
LOGGER.error(e)
|
756 |
-
LOGGER.error(format_exc())
|
757 |
-
return
|
758 |
|
759 |
__PLUGIN__ = "devs"
|
760 |
|
|
|
24 |
from Powers.database.chats_db import Chats
|
25 |
from Powers.database.support_db import SUPPORTS
|
26 |
from Powers.database.users_db import Users
|
|
|
27 |
from Powers.utils.clean_file import remove_markdown_and_html
|
28 |
from Powers.utils.custom_filters import command
|
29 |
from Powers.utils.extract_user import extract_user
|
|
|
737 |
return
|
738 |
|
739 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
740 |
|
741 |
__PLUGIN__ = "devs"
|
742 |
|
Powers/plugins/flood.py
CHANGED
@@ -436,8 +436,11 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
436 |
if y-x <= within:
|
437 |
action = action.split("_")
|
438 |
if len(action) == 2:
|
439 |
-
|
440 |
-
|
|
|
|
|
|
|
441 |
for_how_much = datetime.now() + timedelta(minutes=for_tim)
|
442 |
if to_do == "ban":
|
443 |
try:
|
@@ -452,7 +455,7 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
452 |
],
|
453 |
],
|
454 |
)
|
455 |
-
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Baned\nReason: Spaming"
|
456 |
await m.reply_animation(
|
457 |
animation=str(choice(BAN_GIFS)),
|
458 |
caption=txt,
|
@@ -497,7 +500,7 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
497 |
],
|
498 |
],
|
499 |
)
|
500 |
-
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Muted\nReason: Spaming"
|
501 |
await m.reply_animation(
|
502 |
animation=str(choice(MUTE_GIFS)),
|
503 |
caption=txt,
|
@@ -570,7 +573,7 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
570 |
|
571 |
elif action == "kick":
|
572 |
try:
|
573 |
-
await m.chat.ban_member(u_id, datetime.now()+timedelta(seconds=
|
574 |
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: kicked\nReason: Spaming"
|
575 |
await m.reply_animation(
|
576 |
animation=str(choice(KICK_GIFS)),
|
|
|
436 |
if y-x <= within:
|
437 |
action = action.split("_")
|
438 |
if len(action) == 2:
|
439 |
+
try:
|
440 |
+
to_do = action[0]
|
441 |
+
for_tim = int(action[1].replace("min",""))
|
442 |
+
except:
|
443 |
+
for_tim = 30
|
444 |
for_how_much = datetime.now() + timedelta(minutes=for_tim)
|
445 |
if to_do == "ban":
|
446 |
try:
|
|
|
455 |
],
|
456 |
],
|
457 |
)
|
458 |
+
txt = f"Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Baned\nReason: Spaming\nUntril: {for_how_much}"
|
459 |
await m.reply_animation(
|
460 |
animation=str(choice(BAN_GIFS)),
|
461 |
caption=txt,
|
|
|
500 |
],
|
501 |
],
|
502 |
)
|
503 |
+
txt = f"Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Muted\nReason: Spaming\nUntil: {for_how_much}"
|
504 |
await m.reply_animation(
|
505 |
animation=str(choice(MUTE_GIFS)),
|
506 |
caption=txt,
|
|
|
573 |
|
574 |
elif action == "kick":
|
575 |
try:
|
576 |
+
await m.chat.ban_member(u_id, datetime.now()+timedelta(seconds=1))
|
577 |
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: kicked\nReason: Spaming"
|
578 |
await m.reply_animation(
|
579 |
animation=str(choice(KICK_GIFS)),
|
Powers/plugins/greetings.py
CHANGED
@@ -239,7 +239,7 @@ async def cleannnnn(_, m: Message):
|
|
239 |
@Gojo.on_chat_member_updated(filters.group, group=69)
|
240 |
async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
|
241 |
|
242 |
-
if member.
|
243 |
pass
|
244 |
else:
|
245 |
return
|
@@ -337,7 +337,7 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
|
|
337 |
@Gojo.on_chat_member_updated(filters.group, group=99)
|
338 |
async def member_has_left(c: Gojo, member: ChatMemberUpdated):
|
339 |
|
340 |
-
if member.old_chat_member.status
|
341 |
pass
|
342 |
else:
|
343 |
return
|
|
|
239 |
@Gojo.on_chat_member_updated(filters.group, group=69)
|
240 |
async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
|
241 |
|
242 |
+
if member.old_chat_member.status not in {CMS.MEMBER, CMS.OWNER, CMS.ADMINISTRATOR}:
|
243 |
pass
|
244 |
else:
|
245 |
return
|
|
|
337 |
@Gojo.on_chat_member_updated(filters.group, group=99)
|
338 |
async def member_has_left(c: Gojo, member: ChatMemberUpdated):
|
339 |
|
340 |
+
if member.old_chat_member.status not in [CMS.LEFT, CMS.BANNED, CMS.RESTRICTED]:
|
341 |
pass
|
342 |
else:
|
343 |
return
|
Powers/plugins/scheduled_jobs.py
CHANGED
@@ -1,74 +1,10 @@
|
|
1 |
-
import time as TIME
|
2 |
-
from traceback import format_exc
|
3 |
-
|
4 |
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
5 |
from pyrogram import Client
|
6 |
-
from pyrogram.enums import ChatMemberStatus as CMS
|
7 |
-
from pyrogram.errors import UserNotParticipant
|
8 |
|
9 |
-
from Powers import BDB_URI,
|
10 |
-
from Powers.database.approve_db import Approve
|
11 |
-
from Powers.database.blacklist_db import Blacklist
|
12 |
from Powers.database.chats_db import Chats
|
13 |
-
from Powers.database.disable_db import Disabling
|
14 |
-
from Powers.database.filters_db import Filters
|
15 |
-
from Powers.database.flood_db import Floods
|
16 |
-
from Powers.database.greetings_db import Greetings
|
17 |
-
from Powers.database.notes_db import Notes, NotesSettings
|
18 |
-
from Powers.database.pins_db import Pins
|
19 |
-
from Powers.database.reporting_db import Reporting
|
20 |
-
# from Powers.database.users_db import Users
|
21 |
-
from Powers.database.warns_db import Warns, WarnSettings
|
22 |
-
|
23 |
-
|
24 |
-
async def clean_my_db(c:Client,is_cmd=False, id=None):
|
25 |
-
to_clean = list()
|
26 |
-
chats_list = Chats.list_chats_by_id()
|
27 |
-
to_clean.clear()
|
28 |
-
start = TIME.time()
|
29 |
-
for chats in chats_list:
|
30 |
-
try:
|
31 |
-
stat = await c.get_chat_member(chat_id=chats,user_id=c.me.id)
|
32 |
-
if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]:
|
33 |
-
to_clean.append(chats)
|
34 |
-
except UserNotParticipant:
|
35 |
-
to_clean.append(chats)
|
36 |
-
except Exception as e:
|
37 |
-
LOGGER.error(e)
|
38 |
-
LOGGER.error(format_exc())
|
39 |
-
if not is_cmd:
|
40 |
-
return e
|
41 |
-
else:
|
42 |
-
to_clean.append(chats)
|
43 |
-
for i in to_clean:
|
44 |
-
Approve(i).clean_approve()
|
45 |
-
Blacklist(i).clean_blacklist()
|
46 |
-
Chats.remove_chat(i)
|
47 |
-
Disabling(i).clean_disable()
|
48 |
-
Filters().rm_all_filters(i)
|
49 |
-
Floods().rm_flood(i)
|
50 |
-
Greetings(i).clean_greetings()
|
51 |
-
Notes().rm_all_notes(i)
|
52 |
-
NotesSettings().clean_notes(i)
|
53 |
-
Pins(i).clean_pins()
|
54 |
-
Reporting(i).clean_reporting()
|
55 |
-
Warns(i).clean_warn()
|
56 |
-
WarnSettings(i).clean_warns()
|
57 |
-
x = len(to_clean)
|
58 |
-
txt = f"#INFO\n\nCleaned db:\nTotal chats removed: {x}"
|
59 |
-
to_clean.clear()
|
60 |
-
nums = TIME.time()-start
|
61 |
-
if is_cmd:
|
62 |
-
txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}"
|
63 |
-
txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process"
|
64 |
-
await c.send_message(chat_id=MESSAGE_DUMP,text=txt)
|
65 |
-
return txt
|
66 |
-
else:
|
67 |
-
txt += f"\nClean type: Auto\n\tTook {round(nums,2)} seconds to complete the process"
|
68 |
-
await c.send_message(chat_id=MESSAGE_DUMP,text=txt)
|
69 |
-
return txt
|
70 |
-
|
71 |
|
|
|
72 |
if BDB_URI:
|
73 |
from Powers.plugins import bday_cinfo, bday_info
|
74 |
|
|
|
|
|
|
|
|
|
1 |
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
2 |
from pyrogram import Client
|
|
|
|
|
3 |
|
4 |
+
from Powers import BDB_URI, TIME_ZONE
|
|
|
|
|
5 |
from Powers.database.chats_db import Chats
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
+
# from Powers.database.users_db import Users
|
8 |
if BDB_URI:
|
9 |
from Powers.plugins import bday_cinfo, bday_info
|
10 |
|
Powers/plugins/start.py
CHANGED
@@ -222,7 +222,6 @@ async def help_menu(c: Gojo, m: Message):
|
|
222 |
f"No help_msg found for help_option - {help_option}!!")
|
223 |
return
|
224 |
|
225 |
-
|
226 |
if m.chat.type == ChatType.PRIVATE:
|
227 |
if len(help_msg) >= 1026:
|
228 |
await m.reply_text(
|
@@ -377,8 +376,8 @@ async def get_module_info(c: Gojo, q: CallbackQuery):
|
|
377 |
caption, kb = await get_divided_msg(f"plugins.{module}", back_to_do="commands")
|
378 |
await q.edit_message_caption(
|
379 |
caption,
|
380 |
-
|
381 |
-
|
382 |
)
|
383 |
await q.answer()
|
384 |
return
|
|
|
222 |
f"No help_msg found for help_option - {help_option}!!")
|
223 |
return
|
224 |
|
|
|
225 |
if m.chat.type == ChatType.PRIVATE:
|
226 |
if len(help_msg) >= 1026:
|
227 |
await m.reply_text(
|
|
|
376 |
caption, kb = await get_divided_msg(f"plugins.{module}", back_to_do="commands")
|
377 |
await q.edit_message_caption(
|
378 |
caption,
|
379 |
+
enums.ParseMode.MARKDOWN,
|
380 |
+
kb
|
381 |
)
|
382 |
await q.answer()
|
383 |
return
|
Powers/plugins/web_con.py
CHANGED
@@ -34,7 +34,7 @@ from Powers.utils.web_scrapper import INSTAGRAM, SCRAP_DATA
|
|
34 |
# await m.reply_text("Reply to a video or audio file")
|
35 |
# return
|
36 |
# try:
|
37 |
-
#
|
38 |
# URL = "https://api.audd.io/"
|
39 |
# sizee = (await get_file_size(reply)).split()
|
40 |
# if (int(sizee[0]) <= 30 and sizee[1] == "mb") or sizee[1] == "kb":
|
@@ -55,10 +55,10 @@ from Powers.utils.web_scrapper import INSTAGRAM, SCRAP_DATA
|
|
55 |
# # }
|
56 |
# # result = resp_post(URL,data=BASE_AUDD)
|
57 |
# else:
|
58 |
-
# await
|
59 |
# return
|
60 |
# if result.status_code != 200:
|
61 |
-
# await
|
62 |
# return
|
63 |
# result = result.json()
|
64 |
# data = result["result"]
|
@@ -93,11 +93,11 @@ from Powers.utils.web_scrapper import INSTAGRAM, SCRAP_DATA
|
|
93 |
# if is_genius_lyrics:
|
94 |
# g_k = [IKB("📝 Lyrics",f"lyrics_{Title}:{Artist}")]
|
95 |
# kb.append(g_k)
|
96 |
-
# await
|
97 |
# os.remove(fpath)
|
98 |
# await m.reply_photo(photo,caption=cap,reply_markup=IKM(kb))
|
99 |
# except Exception as e:
|
100 |
-
# await
|
101 |
# await m.reply_text(f"Error\n{e}")
|
102 |
# try:
|
103 |
# os.remove(fpath)
|
@@ -209,7 +209,7 @@ async def remove_background(c: Gojo, m: Message):
|
|
209 |
elif reply.sticker and (reply.sticker.is_video or reply.sticker.is_animated):
|
210 |
await m.reply_text("Reply to normal sticker to remove it's background")
|
211 |
return
|
212 |
-
|
213 |
URL = "https://api.remove.bg/v1.0/removebg"
|
214 |
if reply.sticker:
|
215 |
filee = await reply.download()
|
@@ -220,7 +220,7 @@ async def remove_background(c: Gojo, m: Message):
|
|
220 |
Data = {'size':'auto'}
|
221 |
Headers = {'X-Api-Key':RMBG}
|
222 |
result = resp_post(URL,files=finfo,data=Data,headers=Headers)
|
223 |
-
await
|
224 |
contentType = result.headers.get("content-type")
|
225 |
if result.status_code != 200:
|
226 |
await m.reply_text(f"{result.status_code}:{result.text}")
|
@@ -260,16 +260,16 @@ async def song_down_up(c: Gojo, m: Message):
|
|
260 |
query = splited
|
261 |
else:
|
262 |
query = _id
|
263 |
-
|
264 |
try:
|
265 |
await youtube_downloader(c,m,query, "a")
|
266 |
-
await
|
267 |
return
|
268 |
except KeyError:
|
269 |
-
await
|
270 |
return
|
271 |
except Exception as e:
|
272 |
-
await
|
273 |
LOGGER.error(e)
|
274 |
LOGGER.error(format_exc())
|
275 |
return
|
@@ -286,16 +286,16 @@ async def video_down_up(c: Gojo, m: Message):
|
|
286 |
query = splited
|
287 |
else:
|
288 |
query = _id
|
289 |
-
|
290 |
try:
|
291 |
await youtube_downloader(c,m,query,"v")
|
292 |
-
await
|
293 |
return
|
294 |
except KeyError:
|
295 |
-
await
|
296 |
return
|
297 |
except Exception as e:
|
298 |
-
await
|
299 |
LOGGER.error(e)
|
300 |
LOGGER.error(format_exc())
|
301 |
return
|
|
|
34 |
# await m.reply_text("Reply to a video or audio file")
|
35 |
# return
|
36 |
# try:
|
37 |
+
# to_edit = await m.reply_text("⏳")
|
38 |
# URL = "https://api.audd.io/"
|
39 |
# sizee = (await get_file_size(reply)).split()
|
40 |
# if (int(sizee[0]) <= 30 and sizee[1] == "mb") or sizee[1] == "kb":
|
|
|
55 |
# # }
|
56 |
# # result = resp_post(URL,data=BASE_AUDD)
|
57 |
# else:
|
58 |
+
# await to_edit.edit_text("File size too big\nI can only fetch file of size upto 30 mbs for now")
|
59 |
# return
|
60 |
# if result.status_code != 200:
|
61 |
+
# await to_edit.edit_text(f"{result.status_code}:{result.text}")
|
62 |
# return
|
63 |
# result = result.json()
|
64 |
# data = result["result"]
|
|
|
93 |
# if is_genius_lyrics:
|
94 |
# g_k = [IKB("📝 Lyrics",f"lyrics_{Title}:{Artist}")]
|
95 |
# kb.append(g_k)
|
96 |
+
# await to_edit.delete()
|
97 |
# os.remove(fpath)
|
98 |
# await m.reply_photo(photo,caption=cap,reply_markup=IKM(kb))
|
99 |
# except Exception as e:
|
100 |
+
# await to_edit.delete()
|
101 |
# await m.reply_text(f"Error\n{e}")
|
102 |
# try:
|
103 |
# os.remove(fpath)
|
|
|
209 |
elif reply.sticker and (reply.sticker.is_video or reply.sticker.is_animated):
|
210 |
await m.reply_text("Reply to normal sticker to remove it's background")
|
211 |
return
|
212 |
+
to_edit = await m.reply_text("⏳")
|
213 |
URL = "https://api.remove.bg/v1.0/removebg"
|
214 |
if reply.sticker:
|
215 |
filee = await reply.download()
|
|
|
220 |
Data = {'size':'auto'}
|
221 |
Headers = {'X-Api-Key':RMBG}
|
222 |
result = resp_post(URL,files=finfo,data=Data,headers=Headers)
|
223 |
+
await to_edit.delete()
|
224 |
contentType = result.headers.get("content-type")
|
225 |
if result.status_code != 200:
|
226 |
await m.reply_text(f"{result.status_code}:{result.text}")
|
|
|
260 |
query = splited
|
261 |
else:
|
262 |
query = _id
|
263 |
+
to_edit = await m.reply_text("⏳")
|
264 |
try:
|
265 |
await youtube_downloader(c,m,query, "a")
|
266 |
+
await to_edit.delete()
|
267 |
return
|
268 |
except KeyError:
|
269 |
+
await to_edit.edit_text(f"Failed to find any result")
|
270 |
return
|
271 |
except Exception as e:
|
272 |
+
await to_edit.edit_text(f"Got an error\n{e}")
|
273 |
LOGGER.error(e)
|
274 |
LOGGER.error(format_exc())
|
275 |
return
|
|
|
286 |
query = splited
|
287 |
else:
|
288 |
query = _id
|
289 |
+
to_edit = await m.reply_text("⏳")
|
290 |
try:
|
291 |
await youtube_downloader(c,m,query,"v")
|
292 |
+
await to_edit.delete()
|
293 |
return
|
294 |
except KeyError:
|
295 |
+
await to_edit.edit_text(f"Failed to find any result")
|
296 |
return
|
297 |
except Exception as e:
|
298 |
+
await to_edit.edit_text(f"Got an error\n{e}")
|
299 |
LOGGER.error(e)
|
300 |
LOGGER.error(format_exc())
|
301 |
return
|
Powers/utils/sticker_help.py
CHANGED
@@ -16,6 +16,7 @@ from pyrogram.types import InlineKeyboardMarkup as ikm
|
|
16 |
from pyrogram.types import Message
|
17 |
from unidecode import unidecode
|
18 |
|
|
|
19 |
from Powers.bot_class import Gojo
|
20 |
from Powers.utils.string import encode_decode
|
21 |
|
@@ -204,7 +205,7 @@ async def resize_file_to_sticker_size(file_path: str, length: int = 512, width:
|
|
204 |
else:
|
205 |
im.thumbnail(STICKER_DIMENSIONS)
|
206 |
|
207 |
-
file_pathh = "
|
208 |
im.save(file_pathh)
|
209 |
os.remove(file_path)
|
210 |
return file_pathh
|
|
|
16 |
from pyrogram.types import Message
|
17 |
from unidecode import unidecode
|
18 |
|
19 |
+
from Powers import scrap_dir
|
20 |
from Powers.bot_class import Gojo
|
21 |
from Powers.utils.string import encode_decode
|
22 |
|
|
|
205 |
else:
|
206 |
im.thumbnail(STICKER_DIMENSIONS)
|
207 |
|
208 |
+
file_pathh = f"{scrap_dir}r{str(time()).replace('.','_')}.png"
|
209 |
im.save(file_pathh)
|
210 |
os.remove(file_path)
|
211 |
return file_pathh
|
Powers/utils/web_helpers.py
CHANGED
@@ -8,11 +8,13 @@ from pyrogram.types import InlineKeyboardMarkup as IKM
|
|
8 |
from pyrogram.types import Message
|
9 |
from pytube import YouTube, extract
|
10 |
from youtubesearchpython.__future__ import VideosSearch
|
|
|
11 |
|
12 |
from Powers import youtube_dir
|
13 |
-
from Powers.bot_class import LOGGER,
|
14 |
from Powers.utils.http_helper import *
|
15 |
from Powers.utils.sticker_help import resize_file_to_sticker_size
|
|
|
16 |
|
17 |
backUP = "https://artfiles.alphacoders.com/160/160160.jpeg"
|
18 |
|
@@ -174,16 +176,54 @@ async def song_search(query, max_results=1):
|
|
174 |
pass
|
175 |
return yt_dict
|
176 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
if type_ == "a":
|
180 |
-
|
181 |
video = False
|
182 |
song = True
|
|
|
183 |
elif type_ == "v":
|
184 |
-
|
185 |
video = True
|
186 |
song = False
|
|
|
187 |
# ydl = yt_dlp.YoutubeDL(opts)
|
188 |
dicti = await song_search(query, 1)
|
189 |
if not dicti and type(dicti) != str:
|
@@ -209,15 +249,22 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t
|
|
209 |
vid_dur = get_duration_in_sec(dicti["DURATION"])
|
210 |
published_on = dicti["published"]
|
211 |
if thumb:
|
212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
else:
|
214 |
-
|
|
|
|
|
215 |
# FILE = ydl.extract_info(query,download=video)
|
216 |
url = query
|
217 |
-
thumb = await thumb_.download()
|
218 |
-
if not thumb:
|
219 |
-
thumb = await resize_file_to_sticker_size(thumb, 320, 320)
|
220 |
-
await thumb_.delete()
|
221 |
cap = f"""
|
222 |
⤷ Name: `{f_name}`
|
223 |
⤷ Duration: `{dura}`
|
@@ -237,23 +284,41 @@ Downloaded by: @{c.me.username}
|
|
237 |
]
|
238 |
]
|
239 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
if song:
|
|
|
|
|
|
|
|
|
241 |
msg = await m.reply_text(upload_text)
|
242 |
-
audio_stream = yt.streams.filter(only_audio=True).first()
|
243 |
-
f_path = audio_stream.download()
|
244 |
-
file_path = f"{youtube_dir}{f_name.strip()}.mp3"
|
245 |
-
os.rename(f_path, file_path)
|
246 |
-
|
247 |
await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader, progress=progress, progress_args=(msg, time.time(), upload_text))
|
|
|
248 |
os.remove(file_path)
|
249 |
-
os.remove(thumb)
|
250 |
return
|
251 |
elif video:
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
256 |
await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, progress=progress, progress_args=(msg, time.time(), upload_text))
|
257 |
-
|
258 |
-
os.remove(
|
259 |
return
|
|
|
8 |
from pyrogram.types import Message
|
9 |
from pytube import YouTube, extract
|
10 |
from youtubesearchpython.__future__ import VideosSearch
|
11 |
+
from yt_dlp import YoutubeDL
|
12 |
|
13 |
from Powers import youtube_dir
|
14 |
+
from Powers.bot_class import LOGGER, Gojo
|
15 |
from Powers.utils.http_helper import *
|
16 |
from Powers.utils.sticker_help import resize_file_to_sticker_size
|
17 |
+
from Powers.utils.web_scrapper import SCRAP_DATA
|
18 |
|
19 |
backUP = "https://artfiles.alphacoders.com/160/160160.jpeg"
|
20 |
|
|
|
176 |
pass
|
177 |
return yt_dict
|
178 |
|
179 |
+
song_opts = {
|
180 |
+
"format": "bestaudio",
|
181 |
+
"addmetadata": True,
|
182 |
+
"key": "FFmpegMetadata",
|
183 |
+
"prefer_ffmpeg": True,
|
184 |
+
"geo_bypass": True,
|
185 |
+
"nocheckcertificate": True,
|
186 |
+
"postprocessors": [
|
187 |
+
{
|
188 |
+
"key": "FFmpegExtractAudio",
|
189 |
+
"preferredcodec": "mp3",
|
190 |
+
"preferredquality": "480",
|
191 |
+
}
|
192 |
+
],
|
193 |
+
"outtmpl": "%(id)s",
|
194 |
+
"quiet": True,
|
195 |
+
"logtostderr": False,
|
196 |
+
}
|
197 |
|
198 |
+
video_opts = {
|
199 |
+
"format": "best",
|
200 |
+
"addmetadata": True,
|
201 |
+
"key": "FFmpegMetadata",
|
202 |
+
"prefer_ffmpeg": True,
|
203 |
+
"geo_bypass": True,
|
204 |
+
"nocheckcertificate": True,
|
205 |
+
"postprocessors": [
|
206 |
+
{
|
207 |
+
"key": "FFmpegVideoConvertor",
|
208 |
+
"preferedformat": "mp4",
|
209 |
+
}
|
210 |
+
],
|
211 |
+
"outtmpl": "%(id)s.mp4",
|
212 |
+
"quiet": True,
|
213 |
+
"logtostderr": False,
|
214 |
+
}
|
215 |
+
|
216 |
+
async def youtube_downloader(c: Gojo, m: Message, query: str, type_: str):
|
217 |
if type_ == "a":
|
218 |
+
opts = song_opts
|
219 |
video = False
|
220 |
song = True
|
221 |
+
ext = "mp3"
|
222 |
elif type_ == "v":
|
223 |
+
opts = video_opts
|
224 |
video = True
|
225 |
song = False
|
226 |
+
ext = "mp4"
|
227 |
# ydl = yt_dlp.YoutubeDL(opts)
|
228 |
dicti = await song_search(query, 1)
|
229 |
if not dicti and type(dicti) != str:
|
|
|
249 |
vid_dur = get_duration_in_sec(dicti["DURATION"])
|
250 |
published_on = dicti["published"]
|
251 |
if thumb:
|
252 |
+
try:
|
253 |
+
thumb = SCRAP_DATA(thumb).get_images()
|
254 |
+
thumb = await resize_file_to_sticker_size(thumb[0], 320, 320)
|
255 |
+
except Exception as e:
|
256 |
+
LOGGER.error(e)
|
257 |
+
LOGGER.error(format_exc())
|
258 |
+
LOGGER.info("Using back up image as thumbnail")
|
259 |
+
thumb = SCRAP_DATA(backUP).get_images()
|
260 |
+
thumb = await resize_file_to_sticker_size(thumb[0], 320, 320)
|
261 |
+
|
262 |
else:
|
263 |
+
thumb = SCRAP_DATA(backUP).get_images()
|
264 |
+
thumb = await resize_file_to_sticker_size(thumb[0], 320, 320)
|
265 |
+
|
266 |
# FILE = ydl.extract_info(query,download=video)
|
267 |
url = query
|
|
|
|
|
|
|
|
|
268 |
cap = f"""
|
269 |
⤷ Name: `{f_name}`
|
270 |
⤷ Duration: `{dura}`
|
|
|
284 |
]
|
285 |
]
|
286 |
)
|
287 |
+
|
288 |
+
def get_my_file(opts, ext):
|
289 |
+
try:
|
290 |
+
with YoutubeDL(opts) as ydl:
|
291 |
+
ydl.download([query])
|
292 |
+
info = ydl.extract_info(query, False)
|
293 |
+
file_name = ydl.prepare_filename(info)
|
294 |
+
if len(file_name.rsplit(".", 1)) == 2:
|
295 |
+
pass
|
296 |
+
else:
|
297 |
+
file_name = f"{file_name}.{ext}"
|
298 |
+
new = info['title'].replace('/','|').replace('\\','|')
|
299 |
+
new_file = f"{youtube_dir}{new}.{ext}"
|
300 |
+
os.rename(file_name, new_file)
|
301 |
+
return True, new_file
|
302 |
+
except Exception as e:
|
303 |
+
return False, str(e)
|
304 |
+
|
305 |
if song:
|
306 |
+
success, file_path = get_my_file(opts, ext)
|
307 |
+
if not success:
|
308 |
+
await m.reply_text(file_path)
|
309 |
+
return
|
310 |
msg = await m.reply_text(upload_text)
|
|
|
|
|
|
|
|
|
|
|
311 |
await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader, progress=progress, progress_args=(msg, time.time(), upload_text))
|
312 |
+
await msg.delete()
|
313 |
os.remove(file_path)
|
|
|
314 |
return
|
315 |
elif video:
|
316 |
+
success, file_path = get_my_file(opts, ext)
|
317 |
+
if not success:
|
318 |
+
await m.reply_text(file_path)
|
319 |
+
return
|
320 |
+
msg = await m.reply_text(upload_text)
|
321 |
await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, progress=progress, progress_args=(msg, time.time(), upload_text))
|
322 |
+
await msg.delete()
|
323 |
+
os.remove(file_path)
|
324 |
return
|
Powers/utils/web_scrapper.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
import os
|
2 |
import re
|
3 |
-
import time
|
4 |
from typing import List
|
5 |
|
6 |
import httpx
|
@@ -23,21 +22,22 @@ class SCRAP_DATA:
|
|
23 |
|
24 |
def __init__(self, urls: List[str] or str) -> None:
|
25 |
self.urls = urls
|
26 |
-
self.path =
|
27 |
if not os.path.isdir(self.path):
|
28 |
-
os.makedirs(
|
29 |
|
30 |
def get_images(self) -> list:
|
31 |
images = []
|
32 |
if isinstance(self.urls, str):
|
33 |
requested = httpx.get(self.urls)
|
34 |
try:
|
35 |
-
name = self.path + f"img_{time.
|
36 |
with open(name, "wb") as f:
|
37 |
f.write(requested.content)
|
38 |
images.append(name)
|
39 |
except Exception as e:
|
40 |
LOGGER.error(e)
|
|
|
41 |
requested.close()
|
42 |
else:
|
43 |
for i in self.urls:
|
@@ -46,11 +46,12 @@ class SCRAP_DATA:
|
|
46 |
else:
|
47 |
continue
|
48 |
try:
|
49 |
-
name = self.path + f"img_{time.
|
50 |
with open(name, "wb") as f:
|
51 |
f.write(requested.content)
|
52 |
images.append(name)
|
53 |
except Exception as e:
|
|
|
54 |
LOGGER.error(e)
|
55 |
requested.close()
|
56 |
continue
|
@@ -64,12 +65,13 @@ class SCRAP_DATA:
|
|
64 |
else:
|
65 |
return []
|
66 |
try:
|
67 |
-
name = self.path + f"vid_{time.
|
68 |
with open(name, "wb") as f:
|
69 |
f.write(requested.content)
|
70 |
videos.append(name)
|
71 |
except Exception as e:
|
72 |
LOGGER.error(e)
|
|
|
73 |
requested.close()
|
74 |
else:
|
75 |
for i in self.urls:
|
@@ -78,12 +80,13 @@ class SCRAP_DATA:
|
|
78 |
else:
|
79 |
continue
|
80 |
try:
|
81 |
-
name = self.path + f"vid_{time.
|
82 |
with open(name, "wb") as f:
|
83 |
f.write(requested.content)
|
84 |
videos.append(name)
|
85 |
except Exception as e:
|
86 |
LOGGER.error(e)
|
|
|
87 |
requested.close()
|
88 |
continue
|
89 |
return videos
|
|
|
1 |
import os
|
2 |
import re
|
|
|
3 |
from typing import List
|
4 |
|
5 |
import httpx
|
|
|
22 |
|
23 |
def __init__(self, urls: List[str] or str) -> None:
|
24 |
self.urls = urls
|
25 |
+
self.path = scrap_dir
|
26 |
if not os.path.isdir(self.path):
|
27 |
+
os.makedirs(self.path)
|
28 |
|
29 |
def get_images(self) -> list:
|
30 |
images = []
|
31 |
if isinstance(self.urls, str):
|
32 |
requested = httpx.get(self.urls)
|
33 |
try:
|
34 |
+
name = self.path + f"img_{str(time()).replace('.','_')}.jpg"
|
35 |
with open(name, "wb") as f:
|
36 |
f.write(requested.content)
|
37 |
images.append(name)
|
38 |
except Exception as e:
|
39 |
LOGGER.error(e)
|
40 |
+
LOGGER.error(format_exc())
|
41 |
requested.close()
|
42 |
else:
|
43 |
for i in self.urls:
|
|
|
46 |
else:
|
47 |
continue
|
48 |
try:
|
49 |
+
name = self.path + f"img_{str(time()).replace('.','_')}.jpg"
|
50 |
with open(name, "wb") as f:
|
51 |
f.write(requested.content)
|
52 |
images.append(name)
|
53 |
except Exception as e:
|
54 |
+
LOGGER.error(format_exc())
|
55 |
LOGGER.error(e)
|
56 |
requested.close()
|
57 |
continue
|
|
|
65 |
else:
|
66 |
return []
|
67 |
try:
|
68 |
+
name = self.path + f"vid_{str(time()).replace('.','_')}.mp4"
|
69 |
with open(name, "wb") as f:
|
70 |
f.write(requested.content)
|
71 |
videos.append(name)
|
72 |
except Exception as e:
|
73 |
LOGGER.error(e)
|
74 |
+
LOGGER.error(format_exc())
|
75 |
requested.close()
|
76 |
else:
|
77 |
for i in self.urls:
|
|
|
80 |
else:
|
81 |
continue
|
82 |
try:
|
83 |
+
name = self.path + f"vid_{str(time()).replace('.','_')}.mp4"
|
84 |
with open(name, "wb") as f:
|
85 |
f.write(requested.content)
|
86 |
videos.append(name)
|
87 |
except Exception as e:
|
88 |
LOGGER.error(e)
|
89 |
+
LOGGER.error(format_exc())
|
90 |
requested.close()
|
91 |
continue
|
92 |
return videos
|
Powers/vars.py
CHANGED
@@ -15,7 +15,7 @@ class Config:
|
|
15 |
API_ID = int(config("API_ID", default="123"))
|
16 |
API_HASH = config("API_HASH", default=None)
|
17 |
OWNER_ID = int(config("OWNER_ID", default=1344569458))
|
18 |
-
MESSAGE_DUMP = int(config("MESSAGE_DUMP"))
|
19 |
DEV_USERS = [
|
20 |
int(i)
|
21 |
for i in config(
|
@@ -65,7 +65,7 @@ class Development:
|
|
65 |
API_ID = 12345 # Your APP_ID from Telegram
|
66 |
API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram
|
67 |
OWNER_ID = 1344569458 # Your telegram user id defult to mine
|
68 |
-
MESSAGE_DUMP =
|
69 |
DEV_USERS = []
|
70 |
SUDO_USERS = []
|
71 |
WHITELIST_USERS = []
|
|
|
15 |
API_ID = int(config("API_ID", default="123"))
|
16 |
API_HASH = config("API_HASH", default=None)
|
17 |
OWNER_ID = int(config("OWNER_ID", default=1344569458))
|
18 |
+
MESSAGE_DUMP = int(config("MESSAGE_DUMP", default = "0")) # if not given owner id will be msg dump :)
|
19 |
DEV_USERS = [
|
20 |
int(i)
|
21 |
for i in config(
|
|
|
65 |
API_ID = 12345 # Your APP_ID from Telegram
|
66 |
API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram
|
67 |
OWNER_ID = 1344569458 # Your telegram user id defult to mine
|
68 |
+
MESSAGE_DUMP = 0 # Your Private Group ID for logs if not passed your owner id will be msg dump
|
69 |
DEV_USERS = []
|
70 |
SUDO_USERS = []
|
71 |
WHITELIST_USERS = []
|
README.md
CHANGED
@@ -39,7 +39,7 @@ Not a particular inspiration, inspired by many bots
|
|
39 |
Mainly:
|
40 |
|
41 |
* [Alita_Robot](https://github.com/divideprojects/Alita_Robot)
|
42 |
-
|
43 |
|
44 |
---------
|
45 |
|
@@ -173,7 +173,7 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!--->
|
|
173 |
|
174 |
`DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string.
|
175 |
|
176 |
-
`MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`.
|
177 |
</details>
|
178 |
|
179 |
|
@@ -289,6 +289,8 @@ Some special thanks to the person/repo who/which helped and motivated me to crea
|
|
289 |
|
290 |
* [Alita_Robot](https://github.com/divideprojects/Alita_Robot) for base code.
|
291 |
|
|
|
|
|
292 |
---------
|
293 |
|
294 |
# Powered by [ɢօʝօ ɮօȶֆ](https://github.com/Gojo-Bots)
|
|
|
39 |
Mainly:
|
40 |
|
41 |
* [Alita_Robot](https://github.com/divideprojects/Alita_Robot)
|
42 |
+
* [WilliamButcherBot](https://github.com/TheHamkerCat/WilliamButcherBot)
|
43 |
|
44 |
---------
|
45 |
|
|
|
173 |
|
174 |
`DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string.
|
175 |
|
176 |
+
`MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`. If you don't give it or pass 0 in it your owner id will be the message dump for the bot.
|
177 |
</details>
|
178 |
|
179 |
|
|
|
289 |
|
290 |
* [Alita_Robot](https://github.com/divideprojects/Alita_Robot) for base code.
|
291 |
|
292 |
+
* [WilliamButcherBot](https://github.com/TheHamkerCat/WilliamButcherBot) for few plugins inspirations.
|
293 |
+
|
294 |
---------
|
295 |
|
296 |
# Powered by [ɢօʝօ ɮօȶֆ](https://github.com/Gojo-Bots)
|