mirror of
https://github.com/yasirarism/MissKatyPyro.git
synced 2026-01-01 10:34:51 +00:00
393 lines
17 KiB
Python
393 lines
17 KiB
Python
import os
|
|
import textwrap
|
|
import time
|
|
from datetime import datetime, timedelta
|
|
from logging import getLogger
|
|
|
|
from PIL import Image, ImageChops, ImageDraw, ImageFont
|
|
from pyrogram import enums, filters
|
|
from pyrogram.errors import ChatAdminRequired, MessageTooLong, RPCError
|
|
from pyrogram.types import ChatMemberUpdated, InlineKeyboardButton, InlineKeyboardMarkup
|
|
|
|
from database.users_chats_db import db
|
|
from misskaty import BOT_USERNAME, app
|
|
from misskaty.core.decorator.ratelimiter import ratelimiter
|
|
from misskaty.core.decorator.errors import asyncify, capture_err
|
|
from misskaty.helper.http import http
|
|
from misskaty.helper.localization import use_chat_lang
|
|
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO, SUPPORT_CHAT
|
|
from utils import temp
|
|
|
|
LOGGER = getLogger(__name__)
|
|
|
|
|
|
def circle(pfp, size=(215, 215)):
|
|
pfp = pfp.resize(size, Image.ANTIALIAS).convert("RGBA")
|
|
bigsize = (pfp.size[0] * 3, pfp.size[1] * 3)
|
|
mask = Image.new("L", bigsize, 0)
|
|
draw = ImageDraw.Draw(mask)
|
|
draw.ellipse((0, 0) + bigsize, fill=255)
|
|
mask = mask.resize(pfp.size, Image.ANTIALIAS)
|
|
mask = ImageChops.darker(mask, pfp.split()[-1])
|
|
pfp.putalpha(mask)
|
|
return pfp
|
|
|
|
|
|
def draw_multiple_line_text(image, text, font, text_start_height):
|
|
"""
|
|
From unutbu on [python PIL draw multiline text on image](https://stackoverflow.com/a/7698300/395857)
|
|
"""
|
|
draw = ImageDraw.Draw(image)
|
|
image_width, image_height = image.size
|
|
y_text = text_start_height
|
|
lines = textwrap.wrap(text, width=50)
|
|
for line in lines:
|
|
line_width, line_height = font.getsize(line)
|
|
draw.text(((image_width - line_width) / 2, y_text), line, font=font, fill="black")
|
|
y_text += line_height
|
|
|
|
|
|
@asyncify
|
|
def welcomepic(pic, user, chat, id, strings):
|
|
background = Image.open("assets/bg.png") # <- Background Image (Should be PNG)
|
|
background = background.resize((1024, 500), Image.ANTIALIAS)
|
|
pfp = Image.open(pic).convert("RGBA")
|
|
pfp = circle(pfp)
|
|
pfp = pfp.resize((265, 265)) # Resizes the Profilepicture so it fits perfectly in the circle
|
|
font = ImageFont.truetype("assets/Calistoga-Regular.ttf", 37) # <- Text Font of the Member Count. Change the text size for your preference
|
|
member_text = strings("welcpic_msg").format(userr=user, id=id) # <- Text under the Profilepicture with the Membercount
|
|
draw_multiple_line_text(background, member_text, font, 395)
|
|
draw_multiple_line_text(background, chat, font, 47)
|
|
ImageDraw.Draw(background).text(
|
|
(530, 460),
|
|
f"Generated by @{BOT_USERNAME}",
|
|
font=ImageFont.truetype("assets/Calistoga-Regular.ttf", 28),
|
|
size=20,
|
|
align="right",
|
|
)
|
|
background.paste(pfp, (379, 123), pfp) # Pastes the Profilepicture on the Background Image
|
|
background.save(f"downloads/welcome#{id}.png") # Saves the finished Image in the folder with the filename
|
|
return f"downloads/welcome#{id}.png"
|
|
|
|
|
|
@app.on_chat_member_updated(filters.group & filters.chat([-1001128045651, -1001777794636]))
|
|
@use_chat_lang()
|
|
async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
|
|
if not member.new_chat_member or member.new_chat_member.status in {"banned", "left", "restricted"} or member.old_chat_member:
|
|
return
|
|
user = member.new_chat_member.user if member.new_chat_member else member.from_user
|
|
if user.id in SUDO:
|
|
await c.send_message(
|
|
member.chat.id,
|
|
strings("sudo_join_msg"),
|
|
)
|
|
return
|
|
elif user.is_bot:
|
|
return # ignore bots
|
|
else:
|
|
if (temp.MELCOW).get(f"welcome-{member.chat.id}") is not None:
|
|
try:
|
|
await temp.MELCOW[f"welcome-{member.chat.id}"].delete()
|
|
except:
|
|
pass
|
|
mention = f"<a href='tg://user?id={user.id}'>{user.first_name}</a>"
|
|
joined_date = datetime.fromtimestamp(time.time()).strftime("%Y.%m.%d %H:%M:%S")
|
|
first_name = f"{user.first_name} {user.last_name}" if user.last_name else user.first_name
|
|
id = user.id
|
|
dc = user.dc_id or "Member tanpa PP"
|
|
try:
|
|
pic = await app.download_media(user.photo.big_file_id, file_name=f"pp{user.id}.png")
|
|
except AttributeError:
|
|
pic = "assets/profilepic.png"
|
|
try:
|
|
welcomeimg = await welcomepic(pic, user.first_name, member.chat.title, user.id, strings)
|
|
temp.MELCOW[f"welcome-{member.chat.id}"] = await c.send_photo(
|
|
member.chat.id,
|
|
photo=welcomeimg,
|
|
caption=f"Hai {mention}, Selamat datang digrup {member.chat.title} harap baca rules di pinned message terlebih dahulu.\n\n<b>Nama :<b> <code>{first_name}</code>\n<b>ID :<b> <code>{id}</code>\n<b>DC ID :<b> <code>{dc}</code>\n<b>Tanggal Join :<b> <code>{joined_date}</code>",
|
|
)
|
|
except Exception as e:
|
|
LOGGER.info(e)
|
|
userspammer = ""
|
|
# Spamwatch Detection
|
|
try:
|
|
headers = {"Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"}
|
|
apispamwatch = (await http.get(f"https://api.spamwat.ch/banlist/{user.id}", headers=headers)).json()
|
|
if not apispamwatch.get("error"):
|
|
await app.ban_chat_member(member.chat.id, user.id, datetime.now() + timedelta(seconds=30))
|
|
userspammer += strings("spamwatch_msg").format(umention=user.mention, uid=user.id, reas=apispamwatch.get("reason"))
|
|
except Exception as err:
|
|
LOGGER.error(f"ERROR in Spamwatch Detection. {err}")
|
|
# Combot API Detection
|
|
try:
|
|
apicombot = (await http.get(f"https://api.cas.chat/check?user_id={user.id}")).json()
|
|
if apicombot.get("ok") == "true":
|
|
await app.ban_chat_member(member.chat.id, user.id, datetime.now() + timedelta(seconds=30))
|
|
userspammer += strings("combot_msg").format(umention=user.mention, uid=user.id)
|
|
except Exception as err:
|
|
LOGGER.error(f"ERROR in Combot API Detection. {err}")
|
|
if userspammer != "":
|
|
await c.send_message(member.chat.id, userspammer)
|
|
try:
|
|
os.remove(f"downloads/welcome#{user.id}.png")
|
|
os.remove(f"downloads/pp{user.id}.png")
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
@app.on_message(filters.new_chat_members & filters.group)
|
|
@use_chat_lang()
|
|
async def save_group(bot, message, strings):
|
|
r_j_check = [u.id for u in message.new_chat_members]
|
|
if temp.ME in r_j_check:
|
|
if not await db.get_chat(message.chat.id):
|
|
total = await bot.get_chat_members_count(message.chat.id)
|
|
r_j = message.from_user.mention if message.from_user else "Anonymous"
|
|
await bot.send_message(
|
|
LOG_CHANNEL,
|
|
strings("log_bot_added").format(ttl=message.chat.title, cid=message.chat.id, tot=total, r_j=r_j),
|
|
)
|
|
|
|
await db.add_chat(message.chat.id, message.chat.title)
|
|
if message.chat.id in temp.BANNED_CHATS:
|
|
# Inspired from a boat of a banana tree
|
|
buttons = [[InlineKeyboardButton(strings("support_btn"), url=f"https://t.me/{SUPPORT_CHAT}")]]
|
|
reply_markup = InlineKeyboardMarkup(buttons)
|
|
k = await message.reply(
|
|
text=strings("chat_not_allowed"),
|
|
reply_markup=reply_markup,
|
|
)
|
|
|
|
try:
|
|
await k.pin()
|
|
except:
|
|
pass
|
|
await bot.leave_chat(message.chat.id)
|
|
return
|
|
buttons = [
|
|
[
|
|
InlineKeyboardButton(strings("help_btn"), url=f"https://t.me/{temp.U_NAME}?start=help"),
|
|
InlineKeyboardButton(strings("update_btn"), url="https://t.me/YasirPediaChannel"),
|
|
]
|
|
]
|
|
reply_markup = InlineKeyboardMarkup(buttons)
|
|
await message.reply_text(
|
|
text=strings("welcome_thanks").format(ttl=message.chat.title),
|
|
reply_markup=reply_markup,
|
|
)
|
|
else:
|
|
for u in message.new_chat_members:
|
|
try:
|
|
pic = await app.download_media(u.photo.big_file_id, file_name=f"pp{u.id}.png")
|
|
except AttributeError:
|
|
pic = "assets/profilepic.png"
|
|
if (temp.MELCOW).get(f"welcome-{message.chat.id}") is not None:
|
|
try:
|
|
await temp.MELCOW[f"welcome-{message.chat.id}"].delete()
|
|
except:
|
|
pass
|
|
try:
|
|
welcomeimg = await welcomepic(pic, u.first_name, message.chat.title, u.id, strings)
|
|
temp.MELCOW[f"welcome-{message.chat.id}"] = await app.send_photo(
|
|
message.chat.id,
|
|
photo=welcomeimg,
|
|
caption=strings("capt_welc").format(umention=u.mention, uid=u.id, ttl=message.chat.title),
|
|
)
|
|
userspammer = ""
|
|
# Spamwatch Detection
|
|
try:
|
|
headers = {"Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"}
|
|
apispamwatch = (await http.get(f"https://api.spamwat.ch/banlist/{u.id}", headers=headers)).json()
|
|
if not apispamwatch.get("error"):
|
|
await app.ban_chat_member(message.chat.id, u.id, datetime.now() + timedelta(seconds=30))
|
|
userspammer += strings("spamwatch_msg").format(umention=u.mention, uid=u.id, reas=apispamwatch.get("reason"))
|
|
except Exception as err:
|
|
LOGGER.error(f"ERROR in Spamwatch Detection. {err}")
|
|
# Combot API Detection
|
|
try:
|
|
apicombot = (await http.get(f"https://api.cas.chat/check?user_id={u.id}")).json()
|
|
if apicombot.get("ok") == "true":
|
|
await app.ban_chat_member(message.chat.id, u.id, datetime.now() + timedelta(seconds=30))
|
|
userspammer += strings("combot_msg").format(umention=u.mention, uid=u.id)
|
|
except Exception as err:
|
|
LOGGER.error(f"ERROR in Combot API Detection. {err}")
|
|
if userspammer != "":
|
|
await bot.send_message(message.chat.id, userspammer)
|
|
except:
|
|
pass
|
|
try:
|
|
os.remove(f"downloads/welcome#{u.id}.png")
|
|
os.remove(f"downloads/pp{u.id}.png")
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
@app.on_message(filters.command("leave") & filters.user(SUDO))
|
|
async def leave_a_chat(bot, message):
|
|
if len(message.command) == 1:
|
|
return await message.reply("Give me a chat id")
|
|
chat = message.command[1]
|
|
try:
|
|
chat = int(chat)
|
|
except:
|
|
chat = chat
|
|
try:
|
|
buttons = [[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]]
|
|
reply_markup = InlineKeyboardMarkup(buttons)
|
|
await bot.send_message(
|
|
chat_id=chat,
|
|
text="<b>Hai kawan, \nOwner aku bilang saya harus pergi! Jika kamu ingin menambahkan bot ini lagi silahkan kontak owner bot ini.</b>",
|
|
reply_markup=reply_markup,
|
|
)
|
|
await bot.leave_chat(chat)
|
|
except Exception as e:
|
|
await message.reply(f"Error - {e}")
|
|
await bot.leave_chat(chat)
|
|
|
|
|
|
@app.on_message(filters.command("disable") & filters.user(SUDO))
|
|
async def disable_chat(bot, message):
|
|
if len(message.command) == 1:
|
|
return await message.reply("Give me a chat id")
|
|
r = message.text.split(None)
|
|
if len(r) > 2:
|
|
reason = message.text.split(None, 2)[2]
|
|
chat = message.text.split(None, 2)[1]
|
|
else:
|
|
chat = message.command[1]
|
|
reason = "No reason Provided"
|
|
try:
|
|
chat_ = int(chat)
|
|
except:
|
|
return await message.reply("Give Me A Valid Chat ID")
|
|
cha_t = await db.get_chat(chat_)
|
|
if not cha_t:
|
|
return await message.reply("Chat Not Found In DB")
|
|
if cha_t["is_disabled"]:
|
|
return await message.reply(f"This chat is already disabled:\nReason-<code> {cha_t['reason']} </code>")
|
|
await db.disable_chat(chat_, reason)
|
|
temp.BANNED_CHATS.append(chat_)
|
|
await message.reply("Chat Succesfully Disabled")
|
|
try:
|
|
buttons = [[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]]
|
|
reply_markup = InlineKeyboardMarkup(buttons)
|
|
await bot.send_message(
|
|
chat_id=chat_,
|
|
text=f"<b>Hello Friends, \nMy admin has told me to leave from group so i go! If you wanna add me again contact my support group.</b> \nReason : <code>{reason}</code>",
|
|
reply_markup=reply_markup,
|
|
)
|
|
await bot.leave_chat(chat_)
|
|
except Exception as e:
|
|
await message.reply(f"Error - {e}")
|
|
|
|
|
|
@app.on_message(filters.command("enable") & filters.user(SUDO))
|
|
async def re_enable_chat(bot, message):
|
|
if len(message.command) == 1:
|
|
return await message.reply("Give me a chat id")
|
|
chat = message.command[1]
|
|
try:
|
|
chat_ = int(chat)
|
|
except:
|
|
return await message.reply("Give Me A Valid Chat ID")
|
|
sts = await db.get_chat(int(chat))
|
|
if not sts:
|
|
return await message.reply("Chat Not Found In DB !")
|
|
if not sts.get("is_disabled"):
|
|
return await message.reply("This chat is not yet disabled.")
|
|
await db.re_enable_chat(chat_)
|
|
temp.BANNED_CHATS.remove(chat_)
|
|
await message.reply("Chat Succesfully re-enabled")
|
|
|
|
|
|
# a function for trespassing into others groups, Inspired by a Vazha
|
|
# Not to be used , But Just to showcase his vazhatharam.
|
|
# @app.on_message(filters.command('invite') & filters.user(SUDO))
|
|
async def gen_invite(bot, message):
|
|
if len(message.command) == 1:
|
|
return await message.reply("Give me a chat id")
|
|
chat = message.command[1]
|
|
try:
|
|
chat = int(chat)
|
|
except:
|
|
return await message.reply("Give Me A Valid Chat ID")
|
|
try:
|
|
link = await bot.create_chat_invite_link(chat)
|
|
except ChatAdminRequired:
|
|
return await message.reply("Invite Link Generation Failed, Iam Not Having Sufficient Rights")
|
|
except Exception as e:
|
|
return await message.reply(f"Error {e}")
|
|
await message.reply(f"Here is your Invite Link {link.invite_link}")
|
|
|
|
|
|
@app.on_message(filters.command(["adminlist"], COMMAND_HANDLER))
|
|
@capture_err
|
|
@ratelimiter
|
|
async def adminlist(_, message):
|
|
if message.chat.type == enums.ChatType.PRIVATE:
|
|
return await message.reply("Perintah ini hanya untuk grup")
|
|
try:
|
|
administrators = []
|
|
async for m in app.get_chat_members(message.chat.id, filter=enums.ChatMembersFilter.ADMINISTRATORS):
|
|
administrators.append(f"{m.user.first_name}")
|
|
|
|
res = "".join(f"~ {i}\n" for i in administrators)
|
|
return await message.reply(f"Daftar Admin di <b>{message.chat.title}</b> ({message.chat.id}):\n~ {res}")
|
|
except Exception as e:
|
|
await message.reply(f"ERROR: {str(e)}")
|
|
|
|
|
|
@app.on_message(filters.command(["kickme"], COMMAND_HANDLER))
|
|
@capture_err
|
|
@ratelimiter
|
|
async def kickme(_, message):
|
|
reason = None
|
|
if len(message.text.split()) >= 2:
|
|
reason = message.text.split(None, 1)[1]
|
|
try:
|
|
await message.chat.ban_member(message.from_user.id)
|
|
txt = f"Pengguna {message.from_user.mention} menendang dirinya sendiri. Mungkin dia sedang frustasi 😕"
|
|
txt += f"\n<b>Alasan</b>: {reason}" if reason else "-"
|
|
await message.reply_text(txt)
|
|
await message.chat.unban_member(message.from_user.id)
|
|
except RPCError as ef:
|
|
await message.reply_text(f"Sepertinya ada error, silahkan report ke owner saya. \nERROR: {str(ef)}")
|
|
except Exception as err:
|
|
await message.reply(f"ERROR: {err}")
|
|
|
|
|
|
@app.on_message(filters.command("users") & filters.user(SUDO))
|
|
async def list_users(bot, message):
|
|
# https://t.me/GetTGLink/4184
|
|
raju = await message.reply("Getting List Of Users")
|
|
users = await db.get_all_users()
|
|
out = "Users Saved In DB Are:\n\n"
|
|
async for user in users:
|
|
out += f"<a href=tg://user?id={user['id']}>{user['name']}</a>"
|
|
if user["ban_status"]["is_banned"]:
|
|
out += "( Banned User )"
|
|
out += "\n"
|
|
try:
|
|
await raju.edit_text(out)
|
|
except MessageTooLong:
|
|
with open("users.txt", "w+") as outfile:
|
|
outfile.write(out)
|
|
await message.reply_document("users.txt", caption="List Of Users")
|
|
|
|
|
|
@app.on_message(filters.command("chats") & filters.user(SUDO))
|
|
async def list_chats(bot, message):
|
|
raju = await message.reply("Getting List Of chats")
|
|
chats = await db.get_all_chats()
|
|
out = "Chats Saved In DB Are:\n\n"
|
|
async for chat in chats:
|
|
out += f"**Title:** `{chat['title']}`\n**- ID:** `{chat['id']}`"
|
|
if chat["chat_status"]["is_disabled"]:
|
|
out += "( Disabled Chat )"
|
|
out += "\n"
|
|
try:
|
|
await raju.edit_text(out)
|
|
except MessageTooLong:
|
|
with open("chats.txt", "w+") as outfile:
|
|
outfile.write(out)
|
|
await message.reply_document("chats.txt", caption="List Of Chats")
|