Upload 83 files
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- plugins/__init__.py +105 -0
- plugins/_chatactions.py +253 -0
- plugins/_help.py +136 -0
- plugins/_inline.py +455 -0
- plugins/_ultroid.py +66 -0
- plugins/_userlogs.py +299 -0
- plugins/_wspr.py +204 -0
- plugins/admintools.py +471 -0
- plugins/afk.py +165 -0
- plugins/aiwrapper.py +445 -0
- plugins/antiflood.py +121 -0
- plugins/asstcmd.py +100 -0
- plugins/audiotools.py +163 -0
- plugins/autoban.py +59 -0
- plugins/autopic.py +156 -0
- plugins/beautify.py +197 -0
- plugins/bot.py +366 -0
- plugins/broadcast.py +216 -0
- plugins/button.py +54 -0
- plugins/calculator.py +153 -0
- plugins/channelhacks.py +224 -0
- plugins/chatbot.py +89 -0
- plugins/chats.py +368 -0
- plugins/cleanaction.py +48 -0
- plugins/compressor.py +177 -0
- plugins/converter.py +196 -0
- plugins/core.py +124 -0
- plugins/database.py +77 -0
- plugins/devtools.py +400 -0
- plugins/downloadupload.py +222 -0
- plugins/echo.py +76 -0
- plugins/extra.py +85 -0
- plugins/fakeaction.py +36 -0
- plugins/fileshare.py +95 -0
- plugins/filter.py +100 -0
- plugins/fontgen.py +60 -0
- plugins/forcesubscribe.py +179 -0
- plugins/gdrive.py +232 -0
- plugins/giftools.py +128 -0
- plugins/glitch.py +42 -0
- plugins/globaltools.py +753 -0
- plugins/greetings.py +201 -0
- plugins/imagetools.py +292 -0
- plugins/locks.py +39 -0
- plugins/logo.py +101 -0
- plugins/mediatools.py +147 -0
- plugins/misc.py +140 -0
- plugins/mute.py +210 -0
- plugins/nightmode.py +157 -0
- plugins/notes.py +110 -0
plugins/__init__.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
import asyncio
|
| 9 |
+
import os
|
| 10 |
+
import time
|
| 11 |
+
from random import choice
|
| 12 |
+
|
| 13 |
+
import requests
|
| 14 |
+
from telethon import Button, events
|
| 15 |
+
from telethon.tl import functions, types # pylint:ignore
|
| 16 |
+
|
| 17 |
+
from pyUltroid import *
|
| 18 |
+
from pyUltroid._misc._assistant import asst_cmd, callback, in_pattern
|
| 19 |
+
from pyUltroid._misc._decorators import ultroid_cmd
|
| 20 |
+
from pyUltroid._misc._wrappers import eod, eor
|
| 21 |
+
from pyUltroid.dB import DEVLIST, ULTROID_IMAGES
|
| 22 |
+
from pyUltroid.fns.helper import *
|
| 23 |
+
from pyUltroid.fns.misc import *
|
| 24 |
+
from pyUltroid.fns.tools import *
|
| 25 |
+
from pyUltroid.startup._database import _BaseDatabase as Database
|
| 26 |
+
from pyUltroid.version import __version__, ultroid_version
|
| 27 |
+
from strings import get_help, get_string
|
| 28 |
+
from catbox import CatboxUploader
|
| 29 |
+
|
| 30 |
+
udB: Database
|
| 31 |
+
|
| 32 |
+
Redis = udB.get_key
|
| 33 |
+
con = TgConverter
|
| 34 |
+
quotly = Quotly()
|
| 35 |
+
OWNER_NAME = ultroid_bot.full_name
|
| 36 |
+
OWNER_ID = ultroid_bot.uid
|
| 37 |
+
|
| 38 |
+
ultroid_bot: UltroidClient
|
| 39 |
+
asst: UltroidClient
|
| 40 |
+
|
| 41 |
+
LOG_CHANNEL = udB.get_key("LOG_CHANNEL")
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def inline_pic():
|
| 45 |
+
INLINE_PIC = udB.get_key("INLINE_PIC")
|
| 46 |
+
if INLINE_PIC is None:
|
| 47 |
+
INLINE_PIC = choice(ULTROID_IMAGES)
|
| 48 |
+
elif INLINE_PIC == False:
|
| 49 |
+
INLINE_PIC = None
|
| 50 |
+
return INLINE_PIC
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
Telegraph = telegraph_client()
|
| 54 |
+
cat_uploader = CatboxUploader()
|
| 55 |
+
|
| 56 |
+
upload_file = cat_uploader.upload_file
|
| 57 |
+
|
| 58 |
+
List = []
|
| 59 |
+
Dict = {}
|
| 60 |
+
InlinePlugin = {}
|
| 61 |
+
N = 0
|
| 62 |
+
cmd = ultroid_cmd
|
| 63 |
+
STUFF = {}
|
| 64 |
+
|
| 65 |
+
# Chats, which needs to be ignore for some cases
|
| 66 |
+
# Considerably, there can be many
|
| 67 |
+
# Feel Free to Add Any other...
|
| 68 |
+
|
| 69 |
+
NOSPAM_CHAT = [
|
| 70 |
+
-1001361294038, # UltroidSupportChat
|
| 71 |
+
-1001387666944, # PyrogramChat
|
| 72 |
+
-1001109500936, # TelethonChat
|
| 73 |
+
-1001050982793, # Python
|
| 74 |
+
-1001256902287, # DurovsChat
|
| 75 |
+
-1001473548283, # SharingUserbot
|
| 76 |
+
]
|
| 77 |
+
|
| 78 |
+
KANGING_STR = [
|
| 79 |
+
"Using Witchery to kang this sticker...",
|
| 80 |
+
"Plagiarising hehe...",
|
| 81 |
+
"Inviting this sticker over to my pack...",
|
| 82 |
+
"Kanging this sticker...",
|
| 83 |
+
"Hey that's a nice sticker!\nMind if I kang?!..",
|
| 84 |
+
"Hehe me stel ur stiker...",
|
| 85 |
+
"Ay look over there (☉。☉)!→\nWhile I kang this...",
|
| 86 |
+
"Roses are red violets are blue, kanging this sticker so my pack looks cool",
|
| 87 |
+
"Imprisoning this sticker...",
|
| 88 |
+
"Mr.Steal-Your-Sticker is stealing this sticker... ",
|
| 89 |
+
]
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
ATRA_COL = [
|
| 93 |
+
"DarkCyan",
|
| 94 |
+
"DeepSkyBlue",
|
| 95 |
+
"DarkTurquoise",
|
| 96 |
+
"Cyan",
|
| 97 |
+
"LightSkyBlue",
|
| 98 |
+
"Turquoise",
|
| 99 |
+
"MediumVioletRed",
|
| 100 |
+
"Aquamarine",
|
| 101 |
+
"Lightcyan",
|
| 102 |
+
"Azure",
|
| 103 |
+
"Moccasin",
|
| 104 |
+
"PowderBlue",
|
| 105 |
+
]
|
plugins/_chatactions.py
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
import asyncio
|
| 9 |
+
|
| 10 |
+
from telethon import events
|
| 11 |
+
from telethon.errors.rpcerrorlist import UserNotParticipantError
|
| 12 |
+
from telethon.tl.functions.channels import GetParticipantRequest
|
| 13 |
+
from telethon.utils import get_display_name
|
| 14 |
+
|
| 15 |
+
from pyUltroid.dB import stickers
|
| 16 |
+
from pyUltroid.dB.echo_db import check_echo
|
| 17 |
+
from pyUltroid.dB.forcesub_db import get_forcesetting
|
| 18 |
+
from pyUltroid.dB.gban_mute_db import is_gbanned
|
| 19 |
+
from pyUltroid.dB.greetings_db import get_goodbye, get_welcome, must_thank
|
| 20 |
+
from pyUltroid.dB.nsfw_db import is_profan
|
| 21 |
+
from pyUltroid.fns.helper import inline_mention
|
| 22 |
+
from pyUltroid.fns.tools import async_searcher, create_tl_btn, get_chatbot_reply
|
| 23 |
+
|
| 24 |
+
try:
|
| 25 |
+
from ProfanityDetector import detector
|
| 26 |
+
except ImportError:
|
| 27 |
+
detector = None
|
| 28 |
+
from . import LOG_CHANNEL, LOGS, asst, get_string, types, udB, ultroid_bot
|
| 29 |
+
from ._inline import something
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
@ultroid_bot.on(events.ChatAction())
|
| 33 |
+
async def Function(event):
|
| 34 |
+
try:
|
| 35 |
+
await DummyHandler(event)
|
| 36 |
+
except Exception as er:
|
| 37 |
+
LOGS.exception(er)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
async def DummyHandler(ult):
|
| 41 |
+
# clean chat actions
|
| 42 |
+
key = udB.get_key("CLEANCHAT") or []
|
| 43 |
+
if ult.chat_id in key:
|
| 44 |
+
try:
|
| 45 |
+
await ult.delete()
|
| 46 |
+
except BaseException:
|
| 47 |
+
pass
|
| 48 |
+
|
| 49 |
+
# thank members
|
| 50 |
+
if must_thank(ult.chat_id):
|
| 51 |
+
chat_count = (await ult.client.get_participants(ult.chat_id, limit=0)).total
|
| 52 |
+
if chat_count % 100 == 0:
|
| 53 |
+
stik_id = chat_count / 100 - 1
|
| 54 |
+
sticker = stickers[stik_id]
|
| 55 |
+
await ult.respond(file=sticker)
|
| 56 |
+
# force subscribe
|
| 57 |
+
if (
|
| 58 |
+
udB.get_key("FORCESUB")
|
| 59 |
+
and ((ult.user_joined or ult.user_added))
|
| 60 |
+
and get_forcesetting(ult.chat_id)
|
| 61 |
+
):
|
| 62 |
+
user = await ult.get_user()
|
| 63 |
+
if not user.bot:
|
| 64 |
+
joinchat = get_forcesetting(ult.chat_id)
|
| 65 |
+
try:
|
| 66 |
+
await ultroid_bot(GetParticipantRequest(int(joinchat), user.id))
|
| 67 |
+
except UserNotParticipantError:
|
| 68 |
+
await ultroid_bot.edit_permissions(
|
| 69 |
+
ult.chat_id, user.id, send_messages=False
|
| 70 |
+
)
|
| 71 |
+
res = await ultroid_bot.inline_query(
|
| 72 |
+
asst.me.username, f"fsub {user.id}_{joinchat}"
|
| 73 |
+
)
|
| 74 |
+
await res[0].click(ult.chat_id, reply_to=ult.action_message.id)
|
| 75 |
+
|
| 76 |
+
if ult.user_joined or ult.added_by:
|
| 77 |
+
user = await ult.get_user()
|
| 78 |
+
chat = await ult.get_chat()
|
| 79 |
+
# gbans and @UltroidBans checks
|
| 80 |
+
if udB.get_key("ULTROID_BANS"):
|
| 81 |
+
try:
|
| 82 |
+
is_banned = await async_searcher(
|
| 83 |
+
"https://bans.ultroid.tech/api/status",
|
| 84 |
+
json={"userId": user.id},
|
| 85 |
+
post=True,
|
| 86 |
+
re_json=True,
|
| 87 |
+
)
|
| 88 |
+
if is_banned["is_banned"]:
|
| 89 |
+
await ult.client.edit_permissions(
|
| 90 |
+
chat.id,
|
| 91 |
+
user.id,
|
| 92 |
+
view_messages=False,
|
| 93 |
+
)
|
| 94 |
+
await ult.respond(
|
| 95 |
+
f'**@UltroidBans:** Banned user detected and banned!\n`{str(is_banned)}`.\nBan reason: {is_banned["reason"]}',
|
| 96 |
+
)
|
| 97 |
+
|
| 98 |
+
except BaseException:
|
| 99 |
+
pass
|
| 100 |
+
reason = is_gbanned(user.id)
|
| 101 |
+
if reason and chat.admin_rights:
|
| 102 |
+
try:
|
| 103 |
+
await ult.client.edit_permissions(
|
| 104 |
+
chat.id,
|
| 105 |
+
user.id,
|
| 106 |
+
view_messages=False,
|
| 107 |
+
)
|
| 108 |
+
gban_watch = get_string("can_1").format(inline_mention(user), reason)
|
| 109 |
+
await ult.reply(gban_watch)
|
| 110 |
+
except Exception as er:
|
| 111 |
+
LOGS.exception(er)
|
| 112 |
+
|
| 113 |
+
# greetings
|
| 114 |
+
elif get_welcome(ult.chat_id):
|
| 115 |
+
user = await ult.get_user()
|
| 116 |
+
chat = await ult.get_chat()
|
| 117 |
+
title = chat.title or "this chat"
|
| 118 |
+
count = (
|
| 119 |
+
chat.participants_count
|
| 120 |
+
or (await ult.client.get_participants(chat, limit=0)).total
|
| 121 |
+
)
|
| 122 |
+
mention = inline_mention(user)
|
| 123 |
+
name = user.first_name
|
| 124 |
+
fullname = get_display_name(user)
|
| 125 |
+
uu = user.username
|
| 126 |
+
username = f"@{uu}" if uu else mention
|
| 127 |
+
wel = get_welcome(ult.chat_id)
|
| 128 |
+
msgg = wel["welcome"]
|
| 129 |
+
med = wel["media"] or None
|
| 130 |
+
userid = user.id
|
| 131 |
+
msg = None
|
| 132 |
+
if msgg:
|
| 133 |
+
msg = msgg.format(
|
| 134 |
+
mention=mention,
|
| 135 |
+
group=title,
|
| 136 |
+
count=count,
|
| 137 |
+
name=name,
|
| 138 |
+
fullname=fullname,
|
| 139 |
+
username=username,
|
| 140 |
+
userid=userid,
|
| 141 |
+
)
|
| 142 |
+
if wel.get("button"):
|
| 143 |
+
btn = create_tl_btn(wel["button"])
|
| 144 |
+
await something(ult, msg, med, btn)
|
| 145 |
+
elif msg:
|
| 146 |
+
send = await ult.reply(
|
| 147 |
+
msg,
|
| 148 |
+
file=med,
|
| 149 |
+
)
|
| 150 |
+
await asyncio.sleep(150)
|
| 151 |
+
await send.delete()
|
| 152 |
+
else:
|
| 153 |
+
await ult.reply(file=med)
|
| 154 |
+
elif (ult.user_left or ult.user_kicked) and get_goodbye(ult.chat_id):
|
| 155 |
+
user = await ult.get_user()
|
| 156 |
+
chat = await ult.get_chat()
|
| 157 |
+
title = chat.title or "this chat"
|
| 158 |
+
count = (
|
| 159 |
+
chat.participants_count
|
| 160 |
+
or (await ult.client.get_participants(chat, limit=0)).total
|
| 161 |
+
)
|
| 162 |
+
mention = inline_mention(user)
|
| 163 |
+
name = user.first_name
|
| 164 |
+
fullname = get_display_name(user)
|
| 165 |
+
uu = user.username
|
| 166 |
+
username = f"@{uu}" if uu else mention
|
| 167 |
+
wel = get_goodbye(ult.chat_id)
|
| 168 |
+
msgg = wel["goodbye"]
|
| 169 |
+
med = wel["media"]
|
| 170 |
+
userid = user.id
|
| 171 |
+
msg = None
|
| 172 |
+
if msgg:
|
| 173 |
+
msg = msgg.format(
|
| 174 |
+
mention=mention,
|
| 175 |
+
group=title,
|
| 176 |
+
count=count,
|
| 177 |
+
name=name,
|
| 178 |
+
fullname=fullname,
|
| 179 |
+
username=username,
|
| 180 |
+
userid=userid,
|
| 181 |
+
)
|
| 182 |
+
if wel.get("button"):
|
| 183 |
+
btn = create_tl_btn(wel["button"])
|
| 184 |
+
await something(ult, msg, med, btn)
|
| 185 |
+
elif msg:
|
| 186 |
+
send = await ult.reply(
|
| 187 |
+
msg,
|
| 188 |
+
file=med,
|
| 189 |
+
)
|
| 190 |
+
await asyncio.sleep(150)
|
| 191 |
+
await send.delete()
|
| 192 |
+
else:
|
| 193 |
+
await ult.reply(file=med)
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
@ultroid_bot.on(events.NewMessage(incoming=True))
|
| 197 |
+
async def chatBot_replies(e):
|
| 198 |
+
sender = await e.get_sender()
|
| 199 |
+
if not isinstance(sender, types.User) or sender.bot:
|
| 200 |
+
return
|
| 201 |
+
if check_echo(e.chat_id, e.sender_id):
|
| 202 |
+
try:
|
| 203 |
+
await e.respond(e.message)
|
| 204 |
+
except Exception as er:
|
| 205 |
+
LOGS.exception(er)
|
| 206 |
+
key = udB.get_key("CHATBOT_USERS") or {}
|
| 207 |
+
if e.text and key.get(e.chat_id) and sender.id in key[e.chat_id]:
|
| 208 |
+
msg = await get_chatbot_reply(e.message.message)
|
| 209 |
+
if msg:
|
| 210 |
+
sleep = udB.get_key("CHATBOT_SLEEP") or 1.5
|
| 211 |
+
await asyncio.sleep(sleep)
|
| 212 |
+
await e.reply(msg)
|
| 213 |
+
chat = await e.get_chat()
|
| 214 |
+
if e.is_group and sender.username:
|
| 215 |
+
await uname_stuff(e.sender_id, sender.username, sender.first_name)
|
| 216 |
+
elif e.is_private and chat.username:
|
| 217 |
+
await uname_stuff(e.sender_id, chat.username, chat.first_name)
|
| 218 |
+
if detector and is_profan(e.chat_id) and e.text:
|
| 219 |
+
x, y = detector(e.text)
|
| 220 |
+
if y:
|
| 221 |
+
await e.delete()
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
@ultroid_bot.on(events.Raw(types.UpdateUserName))
|
| 225 |
+
async def uname_change(e):
|
| 226 |
+
await uname_stuff(e.user_id, e.usernames[0] if e.usernames else None, e.first_name)
|
| 227 |
+
|
| 228 |
+
|
| 229 |
+
async def uname_stuff(id, uname, name):
|
| 230 |
+
if udB.get_key("USERNAME_LOG"):
|
| 231 |
+
old_ = udB.get_key("USERNAME_DB") or {}
|
| 232 |
+
old = old_.get(id)
|
| 233 |
+
# Ignore Name Logs
|
| 234 |
+
if old and old == uname:
|
| 235 |
+
return
|
| 236 |
+
if old and uname:
|
| 237 |
+
await asst.send_message(
|
| 238 |
+
LOG_CHANNEL,
|
| 239 |
+
get_string("can_2").format(old, uname),
|
| 240 |
+
)
|
| 241 |
+
elif old:
|
| 242 |
+
await asst.send_message(
|
| 243 |
+
LOG_CHANNEL,
|
| 244 |
+
get_string("can_3").format(f"[{name}](tg://user?id={id})", old),
|
| 245 |
+
)
|
| 246 |
+
elif uname:
|
| 247 |
+
await asst.send_message(
|
| 248 |
+
LOG_CHANNEL,
|
| 249 |
+
get_string("can_4").format(f"[{name}](tg://user?id={id})", uname),
|
| 250 |
+
)
|
| 251 |
+
|
| 252 |
+
old_[id] = uname
|
| 253 |
+
udB.set_key("USERNAME_DB", old_)
|
plugins/_help.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from telethon.errors.rpcerrorlist import (
|
| 9 |
+
BotInlineDisabledError,
|
| 10 |
+
BotMethodInvalidError,
|
| 11 |
+
BotResponseTimeoutError,
|
| 12 |
+
)
|
| 13 |
+
from telethon.tl.custom import Button
|
| 14 |
+
|
| 15 |
+
from pyUltroid.dB._core import HELP, LIST
|
| 16 |
+
from pyUltroid.fns.tools import cmd_regex_replace
|
| 17 |
+
|
| 18 |
+
from . import HNDLR, LOGS, OWNER_NAME, asst, get_string, inline_pic, udB, ultroid_cmd
|
| 19 |
+
|
| 20 |
+
_main_help_menu = [
|
| 21 |
+
[
|
| 22 |
+
Button.inline(get_string("help_4"), data="uh_Official_"),
|
| 23 |
+
Button.inline(get_string("help_5"), data="uh_Addons_"),
|
| 24 |
+
],
|
| 25 |
+
[
|
| 26 |
+
Button.inline(get_string("help_6"), data="uh_VCBot_"),
|
| 27 |
+
Button.inline(get_string("help_7"), data="inlone"),
|
| 28 |
+
],
|
| 29 |
+
[
|
| 30 |
+
Button.inline(get_string("help_8"), data="ownr"),
|
| 31 |
+
Button.url(
|
| 32 |
+
get_string("help_9"), url=f"https://t.me/{asst.me.username}?start=set"
|
| 33 |
+
),
|
| 34 |
+
],
|
| 35 |
+
[Button.inline(get_string("help_10"), data="close")],
|
| 36 |
+
]
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
@ultroid_cmd(pattern="help( (.*)|$)")
|
| 40 |
+
async def _help(ult):
|
| 41 |
+
plug = ult.pattern_match.group(1).strip()
|
| 42 |
+
chat = await ult.get_chat()
|
| 43 |
+
if plug:
|
| 44 |
+
try:
|
| 45 |
+
if plug in HELP["Official"]:
|
| 46 |
+
output = f"**Plugin** - `{plug}`\n"
|
| 47 |
+
for i in HELP["Official"][plug]:
|
| 48 |
+
output += i
|
| 49 |
+
output += "\n© @TeamUltroid"
|
| 50 |
+
await ult.eor(output)
|
| 51 |
+
elif HELP.get("Addons") and plug in HELP["Addons"]:
|
| 52 |
+
output = f"**Plugin** - `{plug}`\n"
|
| 53 |
+
for i in HELP["Addons"][plug]:
|
| 54 |
+
output += i
|
| 55 |
+
output += "\n© @TeamUltroid"
|
| 56 |
+
await ult.eor(output)
|
| 57 |
+
elif HELP.get("VCBot") and plug in HELP["VCBot"]:
|
| 58 |
+
output = f"**Plugin** - `{plug}`\n"
|
| 59 |
+
for i in HELP["VCBot"][plug]:
|
| 60 |
+
output += i
|
| 61 |
+
output += "\n© @TeamUltroid"
|
| 62 |
+
await ult.eor(output)
|
| 63 |
+
else:
|
| 64 |
+
try:
|
| 65 |
+
x = get_string("help_11").format(plug)
|
| 66 |
+
for d in LIST[plug]:
|
| 67 |
+
x += HNDLR + d
|
| 68 |
+
x += "\n"
|
| 69 |
+
x += "\n© @TeamUltroid"
|
| 70 |
+
await ult.eor(x)
|
| 71 |
+
except BaseException:
|
| 72 |
+
file = None
|
| 73 |
+
compare_strings = []
|
| 74 |
+
for file_name in LIST:
|
| 75 |
+
compare_strings.append(file_name)
|
| 76 |
+
value = LIST[file_name]
|
| 77 |
+
for j in value:
|
| 78 |
+
j = cmd_regex_replace(j)
|
| 79 |
+
compare_strings.append(j)
|
| 80 |
+
if j.strip() == plug:
|
| 81 |
+
file = file_name
|
| 82 |
+
break
|
| 83 |
+
if not file:
|
| 84 |
+
# the enter command/plugin name is not found
|
| 85 |
+
text = f"`{plug}` is not a valid plugin!"
|
| 86 |
+
best_match = None
|
| 87 |
+
for _ in compare_strings:
|
| 88 |
+
if plug in _ and not _.startswith("_"):
|
| 89 |
+
best_match = _
|
| 90 |
+
break
|
| 91 |
+
if best_match:
|
| 92 |
+
text += f"\nDid you mean `{best_match}`?"
|
| 93 |
+
return await ult.eor(text)
|
| 94 |
+
output = f"**Command** `{plug}` **found in plugin** - `{file}`\n"
|
| 95 |
+
if file in HELP["Official"]:
|
| 96 |
+
for i in HELP["Official"][file]:
|
| 97 |
+
output += i
|
| 98 |
+
elif HELP.get("Addons") and file in HELP["Addons"]:
|
| 99 |
+
for i in HELP["Addons"][file]:
|
| 100 |
+
output += i
|
| 101 |
+
elif HELP.get("VCBot") and file in HELP["VCBot"]:
|
| 102 |
+
for i in HELP["VCBot"][file]:
|
| 103 |
+
output += i
|
| 104 |
+
output += "\n© @TeamUltroid"
|
| 105 |
+
await ult.eor(output)
|
| 106 |
+
except BaseException as er:
|
| 107 |
+
LOGS.exception(er)
|
| 108 |
+
await ult.eor("Error 🤔 occured.")
|
| 109 |
+
else:
|
| 110 |
+
try:
|
| 111 |
+
results = await ult.client.inline_query(asst.me.username, "ultd")
|
| 112 |
+
except BotMethodInvalidError:
|
| 113 |
+
z = []
|
| 114 |
+
for x in LIST.values():
|
| 115 |
+
z.extend(x)
|
| 116 |
+
cmd = len(z) + 10
|
| 117 |
+
if udB.get_key("MANAGER") and udB.get_key("DUAL_HNDLR") == "/":
|
| 118 |
+
_main_help_menu[2:3] = [[Button.inline("• Manager Help •", "mngbtn")]]
|
| 119 |
+
return await ult.reply(
|
| 120 |
+
get_string("inline_4").format(
|
| 121 |
+
OWNER_NAME,
|
| 122 |
+
len(HELP["Official"]),
|
| 123 |
+
len(HELP["Addons"] if "Addons" in HELP else []),
|
| 124 |
+
cmd,
|
| 125 |
+
),
|
| 126 |
+
file=inline_pic(),
|
| 127 |
+
buttons=_main_help_menu,
|
| 128 |
+
)
|
| 129 |
+
except BotResponseTimeoutError:
|
| 130 |
+
return await ult.eor(
|
| 131 |
+
get_string("help_2").format(HNDLR),
|
| 132 |
+
)
|
| 133 |
+
except BotInlineDisabledError:
|
| 134 |
+
return await ult.eor(get_string("help_3"))
|
| 135 |
+
await results[0].click(chat.id, reply_to=ult.reply_to_msg_id, hide_via=True)
|
| 136 |
+
await ult.delete()
|
plugins/_inline.py
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
import re
|
| 9 |
+
import time
|
| 10 |
+
from datetime import datetime
|
| 11 |
+
from os import remove
|
| 12 |
+
|
| 13 |
+
from git import Repo
|
| 14 |
+
from telethon import Button
|
| 15 |
+
from telethon.tl.types import InputWebDocument, Message
|
| 16 |
+
from telethon.utils import resolve_bot_file_id
|
| 17 |
+
|
| 18 |
+
from pyUltroid._misc._assistant import callback, in_pattern
|
| 19 |
+
from pyUltroid.dB._core import HELP, LIST
|
| 20 |
+
from pyUltroid.fns.helper import gen_chlog, time_formatter, updater
|
| 21 |
+
from pyUltroid.fns.misc import split_list
|
| 22 |
+
|
| 23 |
+
from . import (
|
| 24 |
+
HNDLR,
|
| 25 |
+
LOGS,
|
| 26 |
+
OWNER_NAME,
|
| 27 |
+
InlinePlugin,
|
| 28 |
+
asst,
|
| 29 |
+
get_string,
|
| 30 |
+
inline_pic,
|
| 31 |
+
split_list,
|
| 32 |
+
start_time,
|
| 33 |
+
udB,
|
| 34 |
+
)
|
| 35 |
+
from ._help import _main_help_menu
|
| 36 |
+
|
| 37 |
+
# ================================================#
|
| 38 |
+
|
| 39 |
+
helps = get_string("inline_1")
|
| 40 |
+
|
| 41 |
+
add_ons = udB.get_key("ADDONS")
|
| 42 |
+
|
| 43 |
+
zhelps = get_string("inline_3") if add_ons is False else get_string("inline_2")
|
| 44 |
+
PLUGINS = HELP.get("Official", [])
|
| 45 |
+
ADDONS = HELP.get("Addons", [])
|
| 46 |
+
upage = 0
|
| 47 |
+
# ============================================#
|
| 48 |
+
|
| 49 |
+
# --------------------BUTTONS--------------------#
|
| 50 |
+
|
| 51 |
+
SUP_BUTTONS = [
|
| 52 |
+
[
|
| 53 |
+
Button.url("• Repo •", url="https://github.com/TeamUltroid/Ultroid"),
|
| 54 |
+
Button.url("• Support •", url="t.me/UltroidSupportChat"),
|
| 55 |
+
],
|
| 56 |
+
]
|
| 57 |
+
|
| 58 |
+
# --------------------BUTTONS--------------------#
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
@in_pattern(owner=True, func=lambda x: not x.text)
|
| 62 |
+
async def inline_alive(o):
|
| 63 |
+
TLINK = inline_pic() or "https://graph.org/file/74d6259983e0642923fdb.jpg"
|
| 64 |
+
MSG = "• **Ultroid Userbot •**"
|
| 65 |
+
WEB0 = InputWebDocument(
|
| 66 |
+
"https://graph.org/file/acd4f5d61369f74c5e7a7.jpg", 0, "image/jpg", []
|
| 67 |
+
)
|
| 68 |
+
RES = [
|
| 69 |
+
await o.builder.article(
|
| 70 |
+
type="photo",
|
| 71 |
+
text=MSG,
|
| 72 |
+
include_media=True,
|
| 73 |
+
buttons=SUP_BUTTONS,
|
| 74 |
+
title="Ultroid Userbot",
|
| 75 |
+
description="Userbot | Telethon",
|
| 76 |
+
url=TLINK,
|
| 77 |
+
thumb=WEB0,
|
| 78 |
+
content=InputWebDocument(TLINK, 0, "image/jpg", []),
|
| 79 |
+
)
|
| 80 |
+
]
|
| 81 |
+
await o.answer(
|
| 82 |
+
RES,
|
| 83 |
+
private=True,
|
| 84 |
+
cache_time=300,
|
| 85 |
+
switch_pm="👥 ULTROID PORTAL",
|
| 86 |
+
switch_pm_param="start",
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
@in_pattern("ultd", owner=True)
|
| 91 |
+
async def inline_handler(event):
|
| 92 |
+
z = []
|
| 93 |
+
for x in LIST.values():
|
| 94 |
+
z.extend(x)
|
| 95 |
+
text = get_string("inline_4").format(
|
| 96 |
+
OWNER_NAME,
|
| 97 |
+
len(HELP.get("Official", [])),
|
| 98 |
+
len(HELP.get("Addons", [])),
|
| 99 |
+
len(z),
|
| 100 |
+
)
|
| 101 |
+
if inline_pic():
|
| 102 |
+
result = await event.builder.photo(
|
| 103 |
+
file=inline_pic(),
|
| 104 |
+
link_preview=False,
|
| 105 |
+
text=text,
|
| 106 |
+
buttons=_main_help_menu,
|
| 107 |
+
)
|
| 108 |
+
else:
|
| 109 |
+
result = await event.builder.article(
|
| 110 |
+
title="Ultroid Help Menu", text=text, buttons=_main_help_menu
|
| 111 |
+
)
|
| 112 |
+
await event.answer([result], private=True, cache_time=300, gallery=True)
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
@in_pattern("pasta", owner=True)
|
| 116 |
+
async def _(event):
|
| 117 |
+
ok = event.text.split("-")[1]
|
| 118 |
+
if not ok.startswith("http"):
|
| 119 |
+
link = f"https://spaceb.in/{ok}"
|
| 120 |
+
raw = f"https://spaceb.in/api/v1/documents/{ok}/raw"
|
| 121 |
+
else:
|
| 122 |
+
link = ok
|
| 123 |
+
raw = f"{ok}/raw"
|
| 124 |
+
result = await event.builder.article(
|
| 125 |
+
title="Paste",
|
| 126 |
+
text="Pasted to Spacebin 🌌",
|
| 127 |
+
buttons=[
|
| 128 |
+
[
|
| 129 |
+
Button.url("SpaceBin", url=link),
|
| 130 |
+
Button.url("Raw", url=raw),
|
| 131 |
+
],
|
| 132 |
+
],
|
| 133 |
+
)
|
| 134 |
+
await event.answer([result])
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
@callback("ownr", owner=True)
|
| 138 |
+
async def setting(event):
|
| 139 |
+
z = []
|
| 140 |
+
for x in LIST.values():
|
| 141 |
+
z.extend(x)
|
| 142 |
+
await event.edit(
|
| 143 |
+
get_string("inline_4").format(
|
| 144 |
+
OWNER_NAME,
|
| 145 |
+
len(HELP.get("Official", [])),
|
| 146 |
+
len(HELP.get("Addons", [])),
|
| 147 |
+
len(z),
|
| 148 |
+
),
|
| 149 |
+
file=inline_pic(),
|
| 150 |
+
link_preview=False,
|
| 151 |
+
buttons=[
|
| 152 |
+
[
|
| 153 |
+
Button.inline("•Pɪɴɢ•", data="pkng"),
|
| 154 |
+
Button.inline("•Uᴘᴛɪᴍᴇ•", data="upp"),
|
| 155 |
+
],
|
| 156 |
+
[
|
| 157 |
+
Button.inline("•Stats•", data="alive"),
|
| 158 |
+
Button.inline("•Uᴘᴅᴀᴛᴇ•", data="doupdate"),
|
| 159 |
+
],
|
| 160 |
+
[Button.inline("« Bᴀᴄᴋ", data="open")],
|
| 161 |
+
],
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
_strings = {"Official": helps, "Addons": zhelps, "VCBot": get_string("inline_6")}
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
@callback(re.compile("uh_(.*)"), owner=True)
|
| 169 |
+
async def help_func(ult):
|
| 170 |
+
key, count = ult.data_match.group(1).decode("utf-8").split("_")
|
| 171 |
+
if key == "VCBot" and HELP.get("VCBot") is None:
|
| 172 |
+
return await ult.answer(get_string("help_12"), alert=True)
|
| 173 |
+
elif key == "Addons" and HELP.get("Addons") is None:
|
| 174 |
+
return await ult.answer(get_string("help_13").format(HNDLR), alert=True)
|
| 175 |
+
if "|" in count:
|
| 176 |
+
_, count = count.split("|")
|
| 177 |
+
count = int(count) if count else 0
|
| 178 |
+
text = _strings.get(key, "").format(OWNER_NAME, len(HELP.get(key)))
|
| 179 |
+
await ult.edit(text, buttons=page_num(count, key), link_preview=False)
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
@callback(re.compile("uplugin_(.*)"), owner=True)
|
| 183 |
+
async def uptd_plugin(event):
|
| 184 |
+
key, file = event.data_match.group(1).decode("utf-8").split("_")
|
| 185 |
+
index = None
|
| 186 |
+
if "|" in file:
|
| 187 |
+
file, index = file.split("|")
|
| 188 |
+
key_ = HELP.get(key, [])
|
| 189 |
+
hel_p = f"Plugin Name - `{file}`\n"
|
| 190 |
+
help_ = ""
|
| 191 |
+
try:
|
| 192 |
+
for i in key_[file]:
|
| 193 |
+
help_ += i
|
| 194 |
+
except BaseException:
|
| 195 |
+
if file in LIST:
|
| 196 |
+
help_ = get_string("help_11").format(file)
|
| 197 |
+
for d in LIST[file]:
|
| 198 |
+
help_ += HNDLR + d
|
| 199 |
+
help_ += "\n"
|
| 200 |
+
if not help_:
|
| 201 |
+
help_ = f"{file} has no Detailed Help!"
|
| 202 |
+
help_ += "\n© @TeamUltroid"
|
| 203 |
+
buttons = []
|
| 204 |
+
if inline_pic():
|
| 205 |
+
data = f"sndplug_{key}_{file}"
|
| 206 |
+
if index is not None:
|
| 207 |
+
data += f"|{index}"
|
| 208 |
+
buttons.append(
|
| 209 |
+
[
|
| 210 |
+
Button.inline(
|
| 211 |
+
"« Sᴇɴᴅ Pʟᴜɢɪɴ »",
|
| 212 |
+
data=data,
|
| 213 |
+
)
|
| 214 |
+
]
|
| 215 |
+
)
|
| 216 |
+
data = f"uh_{key}_"
|
| 217 |
+
if index is not None:
|
| 218 |
+
data += f"|{index}"
|
| 219 |
+
buttons.append(
|
| 220 |
+
[
|
| 221 |
+
Button.inline("« Bᴀᴄᴋ", data=data),
|
| 222 |
+
]
|
| 223 |
+
)
|
| 224 |
+
try:
|
| 225 |
+
await event.edit(help_, buttons=buttons)
|
| 226 |
+
except Exception as er:
|
| 227 |
+
LOGS.exception(er)
|
| 228 |
+
help = f"Do `{HNDLR}help {key}` to get list of commands."
|
| 229 |
+
await event.edit(help, buttons=buttons)
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
@callback(data="doupdate", owner=True)
|
| 233 |
+
async def _(event):
|
| 234 |
+
if not await updater():
|
| 235 |
+
return await event.answer(get_string("inline_9"), cache_time=0, alert=True)
|
| 236 |
+
if not inline_pic():
|
| 237 |
+
return await event.answer(f"Do '{HNDLR}update' to update..")
|
| 238 |
+
repo = Repo.init()
|
| 239 |
+
changelog, tl_chnglog = await gen_chlog(
|
| 240 |
+
repo, f"HEAD..upstream/{repo.active_branch}"
|
| 241 |
+
)
|
| 242 |
+
changelog_str = changelog + "\n\n" + get_string("inline_8")
|
| 243 |
+
if len(changelog_str) > 1024:
|
| 244 |
+
await event.edit(get_string("upd_4"))
|
| 245 |
+
with open("ultroid_updates.txt", "w+") as file:
|
| 246 |
+
file.write(tl_chnglog)
|
| 247 |
+
await event.edit(
|
| 248 |
+
get_string("upd_5"),
|
| 249 |
+
file="ultroid_updates.txt",
|
| 250 |
+
buttons=[
|
| 251 |
+
[Button.inline("• Uᴘᴅᴀᴛᴇ Nᴏᴡ •", data="updatenow")],
|
| 252 |
+
[Button.inline("« Bᴀᴄᴋ", data="ownr")],
|
| 253 |
+
],
|
| 254 |
+
)
|
| 255 |
+
remove("ultroid_updates.txt")
|
| 256 |
+
else:
|
| 257 |
+
await event.edit(
|
| 258 |
+
changelog_str,
|
| 259 |
+
buttons=[
|
| 260 |
+
[Button.inline("Update Now", data="updatenow")],
|
| 261 |
+
[Button.inline("« Bᴀᴄᴋ", data="ownr")],
|
| 262 |
+
],
|
| 263 |
+
parse_mode="html",
|
| 264 |
+
)
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
@callback(data="pkng", owner=True)
|
| 268 |
+
async def _(event):
|
| 269 |
+
start = datetime.now()
|
| 270 |
+
end = datetime.now()
|
| 271 |
+
ms = (end - start).microseconds
|
| 272 |
+
pin = f"🌋Pɪɴɢ = {ms} microseconds"
|
| 273 |
+
await event.answer(pin, cache_time=0, alert=True)
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
@callback(data="upp", owner=True)
|
| 277 |
+
async def _(event):
|
| 278 |
+
uptime = time_formatter((time.time() - start_time) * 1000)
|
| 279 |
+
pin = f"🙋Uᴘᴛɪᴍᴇ = {uptime}"
|
| 280 |
+
await event.answer(pin, cache_time=0, alert=True)
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
@callback(data="inlone", owner=True)
|
| 284 |
+
async def _(e):
|
| 285 |
+
_InButtons = [
|
| 286 |
+
Button.switch_inline(_, query=InlinePlugin[_], same_peer=True)
|
| 287 |
+
for _ in list(InlinePlugin.keys())
|
| 288 |
+
]
|
| 289 |
+
InButtons = split_list(_InButtons, 2)
|
| 290 |
+
|
| 291 |
+
button = InButtons.copy()
|
| 292 |
+
button.append(
|
| 293 |
+
[
|
| 294 |
+
Button.inline("« Bᴀᴄᴋ", data="open"),
|
| 295 |
+
],
|
| 296 |
+
)
|
| 297 |
+
await e.edit(buttons=button, link_preview=False)
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
@callback(data="open", owner=True)
|
| 301 |
+
async def opner(event):
|
| 302 |
+
z = []
|
| 303 |
+
for x in LIST.values():
|
| 304 |
+
z.extend(x)
|
| 305 |
+
await event.edit(
|
| 306 |
+
get_string("inline_4").format(
|
| 307 |
+
OWNER_NAME,
|
| 308 |
+
len(HELP.get("Official", [])),
|
| 309 |
+
len(HELP.get("Addons", [])),
|
| 310 |
+
len(z),
|
| 311 |
+
),
|
| 312 |
+
buttons=_main_help_menu,
|
| 313 |
+
link_preview=False,
|
| 314 |
+
)
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
@callback(data="close", owner=True)
|
| 318 |
+
async def on_plug_in_callback_query_handler(event):
|
| 319 |
+
await event.edit(
|
| 320 |
+
get_string("inline_5"),
|
| 321 |
+
buttons=Button.inline("Oᴘᴇɴ Aɢᴀɪɴ", data="open"),
|
| 322 |
+
)
|
| 323 |
+
|
| 324 |
+
|
| 325 |
+
def page_num(index, key):
|
| 326 |
+
rows = udB.get_key("HELP_ROWS") or 5
|
| 327 |
+
cols = udB.get_key("HELP_COLUMNS") or 2
|
| 328 |
+
loaded = HELP.get(key, [])
|
| 329 |
+
emoji = udB.get_key("EMOJI_IN_HELP") or "✘"
|
| 330 |
+
List = [
|
| 331 |
+
Button.inline(f"{emoji} {x} {emoji}", data=f"uplugin_{key}_{x}|{index}")
|
| 332 |
+
for x in sorted(loaded)
|
| 333 |
+
]
|
| 334 |
+
all_ = split_list(List, cols)
|
| 335 |
+
fl_ = split_list(all_, rows)
|
| 336 |
+
try:
|
| 337 |
+
new_ = fl_[index]
|
| 338 |
+
except IndexError:
|
| 339 |
+
new_ = fl_[0] if fl_ else []
|
| 340 |
+
index = 0
|
| 341 |
+
if index == 0 and len(fl_) == 1:
|
| 342 |
+
new_.append([Button.inline("« Bᴀᴄᴋ »", data="open")])
|
| 343 |
+
else:
|
| 344 |
+
new_.append(
|
| 345 |
+
[
|
| 346 |
+
Button.inline(
|
| 347 |
+
"« Pʀᴇᴠɪᴏᴜs",
|
| 348 |
+
data=f"uh_{key}_{index-1}",
|
| 349 |
+
),
|
| 350 |
+
Button.inline("« Bᴀᴄᴋ »", data="open"),
|
| 351 |
+
Button.inline(
|
| 352 |
+
"Nᴇxᴛ »",
|
| 353 |
+
data=f"uh_{key}_{index+1}",
|
| 354 |
+
),
|
| 355 |
+
]
|
| 356 |
+
)
|
| 357 |
+
return new_
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
# --------------------------------------------------------------------------------- #
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
STUFF = {}
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
@in_pattern("stf(.*)", owner=True)
|
| 367 |
+
async def ibuild(e):
|
| 368 |
+
n = e.pattern_match.group(1).strip()
|
| 369 |
+
builder = e.builder
|
| 370 |
+
if not (n and n.isdigit()):
|
| 371 |
+
return
|
| 372 |
+
ok = STUFF.get(int(n))
|
| 373 |
+
txt = ok.get("msg")
|
| 374 |
+
pic = ok.get("media")
|
| 375 |
+
btn = ok.get("button")
|
| 376 |
+
if not (pic or txt):
|
| 377 |
+
txt = "Hey!"
|
| 378 |
+
if pic:
|
| 379 |
+
try:
|
| 380 |
+
include_media = True
|
| 381 |
+
mime_type, _pic = None, None
|
| 382 |
+
cont, results = None, None
|
| 383 |
+
try:
|
| 384 |
+
ext = str(pic).split(".")[-1].lower()
|
| 385 |
+
except BaseException:
|
| 386 |
+
ext = None
|
| 387 |
+
if ext in ["img", "jpg", "png"]:
|
| 388 |
+
_type = "photo"
|
| 389 |
+
mime_type = "image/jpg"
|
| 390 |
+
elif ext in ["mp4", "mkv", "gif"]:
|
| 391 |
+
mime_type = "video/mp4"
|
| 392 |
+
_type = "gif"
|
| 393 |
+
else:
|
| 394 |
+
try:
|
| 395 |
+
if "telethon.tl.types" in str(type(pic)):
|
| 396 |
+
_pic = pic
|
| 397 |
+
else:
|
| 398 |
+
_pic = resolve_bot_file_id(pic)
|
| 399 |
+
except BaseException:
|
| 400 |
+
pass
|
| 401 |
+
if _pic:
|
| 402 |
+
results = [
|
| 403 |
+
await builder.document(
|
| 404 |
+
_pic,
|
| 405 |
+
title="Ultroid Op",
|
| 406 |
+
text=txt,
|
| 407 |
+
description="@TeamUltroid",
|
| 408 |
+
buttons=btn,
|
| 409 |
+
link_preview=False,
|
| 410 |
+
)
|
| 411 |
+
]
|
| 412 |
+
else:
|
| 413 |
+
_type = "article"
|
| 414 |
+
include_media = False
|
| 415 |
+
if not results:
|
| 416 |
+
if include_media:
|
| 417 |
+
cont = InputWebDocument(pic, 0, mime_type, [])
|
| 418 |
+
results = [
|
| 419 |
+
await builder.article(
|
| 420 |
+
title="Ultroid Op",
|
| 421 |
+
type=_type,
|
| 422 |
+
text=txt,
|
| 423 |
+
description="@TeamUltroid",
|
| 424 |
+
include_media=include_media,
|
| 425 |
+
buttons=btn,
|
| 426 |
+
thumb=cont,
|
| 427 |
+
content=cont,
|
| 428 |
+
link_preview=False,
|
| 429 |
+
)
|
| 430 |
+
]
|
| 431 |
+
return await e.answer(results)
|
| 432 |
+
except Exception as er:
|
| 433 |
+
LOGS.exception(er)
|
| 434 |
+
result = [
|
| 435 |
+
await builder.article("Ultroid Op", text=txt, link_preview=False, buttons=btn)
|
| 436 |
+
]
|
| 437 |
+
await e.answer(result)
|
| 438 |
+
|
| 439 |
+
|
| 440 |
+
async def something(e, msg, media, button, reply=True, chat=None):
|
| 441 |
+
if e.client._bot:
|
| 442 |
+
return await e.reply(msg, file=media, buttons=button)
|
| 443 |
+
num = len(STUFF) + 1
|
| 444 |
+
STUFF.update({num: {"msg": msg, "media": media, "button": button}})
|
| 445 |
+
try:
|
| 446 |
+
res = await e.client.inline_query(asst.me.username, f"stf{num}")
|
| 447 |
+
return await res[0].click(
|
| 448 |
+
chat or e.chat_id,
|
| 449 |
+
reply_to=bool(isinstance(e, Message) and reply),
|
| 450 |
+
hide_via=True,
|
| 451 |
+
silent=True,
|
| 452 |
+
)
|
| 453 |
+
|
| 454 |
+
except Exception as er:
|
| 455 |
+
LOGS.exception(er)
|
plugins/_ultroid.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from telethon.errors import (
|
| 9 |
+
BotMethodInvalidError,
|
| 10 |
+
ChatSendInlineForbiddenError,
|
| 11 |
+
ChatSendMediaForbiddenError,
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
from . import LOG_CHANNEL, LOGS, Button, asst, eor, get_string, ultroid_cmd
|
| 15 |
+
|
| 16 |
+
REPOMSG = """
|
| 17 |
+
• **ULTROID USERBOT** •\n
|
| 18 |
+
• Repo - [Click Here](https://github.com/TeamUltroid/Ultroid)
|
| 19 |
+
• Addons - [Click Here](https://github.com/TeamUltroid/UltroidAddons)
|
| 20 |
+
• Support - @UltroidSupportChat
|
| 21 |
+
"""
|
| 22 |
+
|
| 23 |
+
RP_BUTTONS = [
|
| 24 |
+
[
|
| 25 |
+
Button.url(get_string("bot_3"), "https://github.com/TeamUltroid/Ultroid"),
|
| 26 |
+
Button.url("Addons", "https://github.com/TeamUltroid/UltroidAddons"),
|
| 27 |
+
],
|
| 28 |
+
[Button.url("Support Group", "t.me/UltroidSupportChat")],
|
| 29 |
+
]
|
| 30 |
+
|
| 31 |
+
ULTSTRING = """🎇 **Thanks for Deploying Ultroid Userbot!**
|
| 32 |
+
|
| 33 |
+
• Here, are the Some Basic stuff from, where you can Know, about its Usage."""
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
@ultroid_cmd(
|
| 37 |
+
pattern="repo$",
|
| 38 |
+
manager=True,
|
| 39 |
+
)
|
| 40 |
+
async def repify(e):
|
| 41 |
+
try:
|
| 42 |
+
q = await e.client.inline_query(asst.me.username, "")
|
| 43 |
+
await q[0].click(e.chat_id)
|
| 44 |
+
return await e.delete()
|
| 45 |
+
except (
|
| 46 |
+
ChatSendInlineForbiddenError,
|
| 47 |
+
ChatSendMediaForbiddenError,
|
| 48 |
+
BotMethodInvalidError,
|
| 49 |
+
):
|
| 50 |
+
pass
|
| 51 |
+
except Exception as er:
|
| 52 |
+
LOGS.info(f"Error while repo command : {str(er)}")
|
| 53 |
+
await e.eor(REPOMSG)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
@ultroid_cmd(pattern="ultroid$")
|
| 57 |
+
async def useUltroid(rs):
|
| 58 |
+
button = Button.inline("Start >>", "initft_2")
|
| 59 |
+
msg = await asst.send_message(
|
| 60 |
+
LOG_CHANNEL,
|
| 61 |
+
ULTSTRING,
|
| 62 |
+
file="https://graph.org/file/54a917cc9dbb94733ea5f.jpg",
|
| 63 |
+
buttons=button,
|
| 64 |
+
)
|
| 65 |
+
if not (rs.chat_id == LOG_CHANNEL and rs.client._bot):
|
| 66 |
+
await eor(rs, f"**[Click Here]({msg.message_link})**")
|
plugins/_userlogs.py
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
import os
|
| 9 |
+
import re
|
| 10 |
+
|
| 11 |
+
from telethon.errors.rpcerrorlist import (
|
| 12 |
+
ChannelPrivateError,
|
| 13 |
+
ChatWriteForbiddenError,
|
| 14 |
+
MediaCaptionTooLongError,
|
| 15 |
+
MediaEmptyError,
|
| 16 |
+
MessageTooLongError,
|
| 17 |
+
PeerIdInvalidError,
|
| 18 |
+
UserNotParticipantError,
|
| 19 |
+
)
|
| 20 |
+
from telethon.tl.types import MessageEntityMention, MessageEntityMentionName, User
|
| 21 |
+
from telethon.utils import get_display_name
|
| 22 |
+
|
| 23 |
+
from pyUltroid.dB.botchat_db import tag_add, who_tag
|
| 24 |
+
|
| 25 |
+
from . import (
|
| 26 |
+
LOG_CHANNEL,
|
| 27 |
+
LOGS,
|
| 28 |
+
Button,
|
| 29 |
+
asst,
|
| 30 |
+
callback,
|
| 31 |
+
events,
|
| 32 |
+
get_string,
|
| 33 |
+
inline_mention,
|
| 34 |
+
udB,
|
| 35 |
+
ultroid_bot,
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
CACHE_SPAM = {}
|
| 39 |
+
TAG_EDITS = {}
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
@ultroid_bot.on(
|
| 43 |
+
events.NewMessage(
|
| 44 |
+
incoming=True,
|
| 45 |
+
func=lambda e: (e.mentioned),
|
| 46 |
+
),
|
| 47 |
+
)
|
| 48 |
+
async def all_messages_catcher(e):
|
| 49 |
+
x = await e.get_sender()
|
| 50 |
+
if isinstance(x, User) and (x.bot or x.verified):
|
| 51 |
+
return
|
| 52 |
+
if not udB.get_key("TAG_LOG"):
|
| 53 |
+
return
|
| 54 |
+
NEEDTOLOG = udB.get_key("TAG_LOG")
|
| 55 |
+
if e.chat_id == NEEDTOLOG:
|
| 56 |
+
return
|
| 57 |
+
buttons = await parse_buttons(e)
|
| 58 |
+
try:
|
| 59 |
+
sent = await asst.send_message(NEEDTOLOG, e.message, buttons=buttons)
|
| 60 |
+
if TAG_EDITS.get(e.chat_id):
|
| 61 |
+
TAG_EDITS[e.chat_id].update({e.id: {"id": sent.id, "msg": e}})
|
| 62 |
+
else:
|
| 63 |
+
TAG_EDITS.update({e.chat_id: {e.id: {"id": sent.id, "msg": e}}})
|
| 64 |
+
tag_add(sent.id, e.chat_id, e.id)
|
| 65 |
+
except MediaEmptyError as er:
|
| 66 |
+
LOGS.debug(f"handling {er}.")
|
| 67 |
+
try:
|
| 68 |
+
msg = await asst.get_messages(e.chat_id, ids=e.id)
|
| 69 |
+
sent = await asst.send_message(NEEDTOLOG, msg, buttons=buttons)
|
| 70 |
+
if TAG_EDITS.get(e.chat_id):
|
| 71 |
+
TAG_EDITS[e.chat_id].update({e.id: {"id": sent.id, "msg": e}})
|
| 72 |
+
else:
|
| 73 |
+
TAG_EDITS.update({e.chat_id: {e.id: {"id": sent.id, "msg": e}}})
|
| 74 |
+
tag_add(sent.id, e.chat_id, e.id)
|
| 75 |
+
except Exception as me:
|
| 76 |
+
if not isinstance(me, (PeerIdInvalidError, ValueError)):
|
| 77 |
+
LOGS.exception(me)
|
| 78 |
+
if e.photo or e.sticker or e.gif:
|
| 79 |
+
try:
|
| 80 |
+
media = await e.download_media()
|
| 81 |
+
sent = await asst.send_message(
|
| 82 |
+
NEEDTOLOG, e.message.text, file=media, buttons=buttons
|
| 83 |
+
)
|
| 84 |
+
if TAG_EDITS.get(e.chat_id):
|
| 85 |
+
TAG_EDITS[e.chat_id].update({e.id: {"id": sent.id, "msg": e}})
|
| 86 |
+
else:
|
| 87 |
+
TAG_EDITS.update({e.chat_id: {e.id: {"id": sent.id, "msg": e}}})
|
| 88 |
+
return os.remove(media)
|
| 89 |
+
except Exception as er:
|
| 90 |
+
LOGS.exception(er)
|
| 91 |
+
await asst.send_message(NEEDTOLOG, get_string("com_4"), buttons=buttons)
|
| 92 |
+
except (PeerIdInvalidError, ValueError) as er:
|
| 93 |
+
LOGS.exception(er)
|
| 94 |
+
try:
|
| 95 |
+
CACHE_SPAM[NEEDTOLOG]
|
| 96 |
+
except KeyError:
|
| 97 |
+
await asst.send_message(
|
| 98 |
+
udB.get_key("LOG_CHANNEL"), get_string("userlogs_1")
|
| 99 |
+
)
|
| 100 |
+
CACHE_SPAM.update({NEEDTOLOG: True})
|
| 101 |
+
except ChatWriteForbiddenError:
|
| 102 |
+
try:
|
| 103 |
+
await asst.get_permissions(NEEDTOLOG, "me")
|
| 104 |
+
MSG = get_string("userlogs_4")
|
| 105 |
+
except UserNotParticipantError:
|
| 106 |
+
MSG = get_string("userlogs_2")
|
| 107 |
+
try:
|
| 108 |
+
CACHE_SPAM[NEEDTOLOG]
|
| 109 |
+
except KeyError:
|
| 110 |
+
await asst.send_message(LOG_CHANNEL, MSG)
|
| 111 |
+
CACHE_SPAM.update({NEEDTOLOG: True})
|
| 112 |
+
except Exception as er:
|
| 113 |
+
LOGS.exception(er)
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
if udB.get_key("TAG_LOG"):
|
| 117 |
+
|
| 118 |
+
@ultroid_bot.on(events.MessageEdited(func=lambda x: not x.out))
|
| 119 |
+
async def upd_edits(event):
|
| 120 |
+
x = event.sender
|
| 121 |
+
if isinstance(x, User) and (x.bot or x.verified):
|
| 122 |
+
return
|
| 123 |
+
if event.chat_id not in TAG_EDITS:
|
| 124 |
+
if event.sender_id == udB.get_key("TAG_LOG"):
|
| 125 |
+
return
|
| 126 |
+
if event.is_private:
|
| 127 |
+
return
|
| 128 |
+
if entities := event.get_entities_text():
|
| 129 |
+
is_self = False
|
| 130 |
+
username = event.client.me.username
|
| 131 |
+
if username:
|
| 132 |
+
username = username.lower()
|
| 133 |
+
for ent, text in entities:
|
| 134 |
+
if isinstance(ent, MessageEntityMention):
|
| 135 |
+
is_self = text[1:].lower() == username
|
| 136 |
+
elif isinstance(ent, MessageEntityMentionName):
|
| 137 |
+
is_self = ent.user_id == event.client.me.id
|
| 138 |
+
if is_self:
|
| 139 |
+
text = f"**#Edited & #Mentioned**\n\n{event.text}"
|
| 140 |
+
try:
|
| 141 |
+
sent = await asst.send_message(
|
| 142 |
+
udB.get_key("TAG_LOG"),
|
| 143 |
+
text,
|
| 144 |
+
buttons=await parse_buttons(event),
|
| 145 |
+
)
|
| 146 |
+
except Exception as er:
|
| 147 |
+
return LOGS.exception(er)
|
| 148 |
+
if TAG_EDITS.get(event.chat_id):
|
| 149 |
+
TAG_EDITS[event.chat_id].update({event.id: {"id": sent.id}})
|
| 150 |
+
else:
|
| 151 |
+
TAG_EDITS.update({event.chat_id: {event.id: {"id": sent.id}}})
|
| 152 |
+
return
|
| 153 |
+
d_ = TAG_EDITS[event.chat_id]
|
| 154 |
+
if not d_.get(event.id):
|
| 155 |
+
return
|
| 156 |
+
d_ = d_[event.id]
|
| 157 |
+
if d_["msg"].text == event.text:
|
| 158 |
+
return
|
| 159 |
+
msg = None
|
| 160 |
+
if d_.get("count"):
|
| 161 |
+
d_["count"] += 1
|
| 162 |
+
else:
|
| 163 |
+
msg = True
|
| 164 |
+
d_.update({"count": 1})
|
| 165 |
+
if d_["count"] > 10:
|
| 166 |
+
return # some limit to take edits
|
| 167 |
+
try:
|
| 168 |
+
MSG = await asst.get_messages(udB.get_key("TAG_LOG"), ids=d_["id"])
|
| 169 |
+
except Exception as er:
|
| 170 |
+
return LOGS.exception(er)
|
| 171 |
+
TEXT = MSG.text
|
| 172 |
+
if msg:
|
| 173 |
+
TEXT += "\n\n🖋 **Later Edited to !**"
|
| 174 |
+
strf = event.edit_date.strftime("%H:%M:%S")
|
| 175 |
+
if "\n" not in event.text:
|
| 176 |
+
TEXT += f"\n• `{strf}` : {event.text}"
|
| 177 |
+
else:
|
| 178 |
+
TEXT += f"\n• `{strf}` :\n-> {event.text}"
|
| 179 |
+
if d_["count"] == 10:
|
| 180 |
+
TEXT += "\n\n• __Only the first 10 Edits are shown.__"
|
| 181 |
+
try:
|
| 182 |
+
msg = await MSG.edit(TEXT, buttons=await parse_buttons(event))
|
| 183 |
+
d_["msg"] = msg
|
| 184 |
+
except (MessageTooLongError, MediaCaptionTooLongError):
|
| 185 |
+
del TAG_EDITS[event.chat_id][event.id]
|
| 186 |
+
except Exception as er:
|
| 187 |
+
LOGS.exception(er)
|
| 188 |
+
|
| 189 |
+
@ultroid_bot.on(
|
| 190 |
+
events.NewMessage(
|
| 191 |
+
outgoing=True,
|
| 192 |
+
chats=[udB.get_key("TAG_LOG")],
|
| 193 |
+
func=lambda e: e.reply_to,
|
| 194 |
+
)
|
| 195 |
+
)
|
| 196 |
+
async def idk(e):
|
| 197 |
+
id = e.reply_to_msg_id
|
| 198 |
+
chat, msg = who_tag(id)
|
| 199 |
+
if chat and msg:
|
| 200 |
+
try:
|
| 201 |
+
await ultroid_bot.send_message(chat, e.message, reply_to=msg)
|
| 202 |
+
except BaseException as er:
|
| 203 |
+
LOGS.exception(er)
|
| 204 |
+
|
| 205 |
+
|
| 206 |
+
# log for assistant/user joins/add
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
async def when_added_or_joined(event):
|
| 210 |
+
user = await event.get_user()
|
| 211 |
+
chat = await event.get_chat()
|
| 212 |
+
if not (user and user.is_self):
|
| 213 |
+
return
|
| 214 |
+
if getattr(chat, "username", None):
|
| 215 |
+
chat = f"[{chat.title}](https://t.me/{chat.username}/{event.action_message.id})"
|
| 216 |
+
else:
|
| 217 |
+
chat = f"[{chat.title}](https://t.me/c/{chat.id}/{event.action_message.id})"
|
| 218 |
+
key = "bot" if event.client._bot else "user"
|
| 219 |
+
buttons = Button.inline(
|
| 220 |
+
get_string("userlogs_3"), data=f"leave_ch_{event.chat_id}|{key}"
|
| 221 |
+
)
|
| 222 |
+
if event.user_added:
|
| 223 |
+
tmp = event.added_by
|
| 224 |
+
text = f"#ADD_LOG\n\n{inline_mention(tmp)} just added {inline_mention(user)} to {chat}."
|
| 225 |
+
elif event.from_request:
|
| 226 |
+
text = f"#APPROVAL_LOG\n\n{inline_mention(user)} just got Chat Join Approval to {chat}."
|
| 227 |
+
else:
|
| 228 |
+
text = f"#JOIN_LOG\n\n{inline_mention(user)} just joined {chat}."
|
| 229 |
+
await asst.send_message(udB.get_key("LOG_CHANNEL"), text, buttons=buttons)
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
asst.add_event_handler(
|
| 233 |
+
when_added_or_joined, events.ChatAction(func=lambda x: x.user_added)
|
| 234 |
+
)
|
| 235 |
+
ultroid_bot.add_event_handler(
|
| 236 |
+
when_added_or_joined,
|
| 237 |
+
events.ChatAction(func=lambda x: x.user_added or x.user_joined),
|
| 238 |
+
)
|
| 239 |
+
_client = {"bot": asst, "user": ultroid_bot}
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
@callback(
|
| 243 |
+
re.compile(
|
| 244 |
+
"leave_ch_(.*)",
|
| 245 |
+
),
|
| 246 |
+
from_users=[ultroid_bot.uid],
|
| 247 |
+
)
|
| 248 |
+
async def leave_ch_at(event):
|
| 249 |
+
cht = event.data_match.group(1).decode("UTF-8")
|
| 250 |
+
ch_id, client = cht.split("|")
|
| 251 |
+
try:
|
| 252 |
+
client = _client[client]
|
| 253 |
+
except KeyError:
|
| 254 |
+
return
|
| 255 |
+
try:
|
| 256 |
+
name = (await client.get_entity(int(ch_id))).title
|
| 257 |
+
await client.delete_dialog(int(ch_id))
|
| 258 |
+
except UserNotParticipantError:
|
| 259 |
+
pass
|
| 260 |
+
except ChannelPrivateError:
|
| 261 |
+
return await event.edit(
|
| 262 |
+
"`[CANT_ACCESS_CHAT]` `Maybe already left or got banned.`"
|
| 263 |
+
)
|
| 264 |
+
except Exception as er:
|
| 265 |
+
LOGS.exception(er)
|
| 266 |
+
return await event.answer(str(er))
|
| 267 |
+
await event.edit(get_string("userlogs_5").format(name))
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
@callback("do_nothing")
|
| 271 |
+
async def _(event):
|
| 272 |
+
await event.answer()
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
async def parse_buttons(event):
|
| 276 |
+
y, x = event.chat, event.sender
|
| 277 |
+
where_n, who_n = get_display_name(y), get_display_name(x)
|
| 278 |
+
where_l = event.message_link
|
| 279 |
+
buttons = [[Button.url(where_n, where_l)]]
|
| 280 |
+
if isinstance(x, User) and x.username:
|
| 281 |
+
try:
|
| 282 |
+
buttons.append(
|
| 283 |
+
[Button.mention(who_n, await asst.get_input_entity(x.username))]
|
| 284 |
+
)
|
| 285 |
+
except Exception as er:
|
| 286 |
+
LOGS.exception(er)
|
| 287 |
+
buttons.append([Button.url(who_n, f"t.me/{x.username}")])
|
| 288 |
+
elif getattr(x, "username"):
|
| 289 |
+
buttons.append([Button.url(who_n, f"t.me/{x.username}")])
|
| 290 |
+
else:
|
| 291 |
+
buttons.append([Button.url(who_n, where_l)])
|
| 292 |
+
replied = await event.get_reply_message()
|
| 293 |
+
if replied and replied.out:
|
| 294 |
+
button = Button.url("Replied to", replied.message_link)
|
| 295 |
+
if len(who_n) > 7:
|
| 296 |
+
buttons.append([button])
|
| 297 |
+
else:
|
| 298 |
+
buttons[-1].append(button)
|
| 299 |
+
return buttons
|
plugins/_wspr.py
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
import re
|
| 9 |
+
|
| 10 |
+
from telethon import Button
|
| 11 |
+
from telethon.errors.rpcerrorlist import (
|
| 12 |
+
BotInlineDisabledError,
|
| 13 |
+
BotResponseTimeoutError,
|
| 14 |
+
MessageNotModifiedError,
|
| 15 |
+
)
|
| 16 |
+
from telethon.tl import types
|
| 17 |
+
from telethon.tl.functions.users import GetFullUserRequest as gu
|
| 18 |
+
|
| 19 |
+
from . import (
|
| 20 |
+
HNDLR,
|
| 21 |
+
LOGS,
|
| 22 |
+
asst,
|
| 23 |
+
callback,
|
| 24 |
+
get_string,
|
| 25 |
+
in_pattern,
|
| 26 |
+
inline_mention,
|
| 27 |
+
ultroid_bot,
|
| 28 |
+
ultroid_cmd,
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
buddhhu = {}
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
@ultroid_cmd(
|
| 35 |
+
pattern="wspr( (.*)|$)",
|
| 36 |
+
)
|
| 37 |
+
async def _(e):
|
| 38 |
+
if e.reply_to_msg_id:
|
| 39 |
+
okk = await e.get_reply_message()
|
| 40 |
+
put = f"@{okk.sender.username}" if okk.sender.username else okk.sender_id
|
| 41 |
+
else:
|
| 42 |
+
put = e.pattern_match.group(1).strip()
|
| 43 |
+
if put:
|
| 44 |
+
try:
|
| 45 |
+
results = await e.client.inline_query(asst.me.username, f"msg {put}")
|
| 46 |
+
except BotResponseTimeoutError:
|
| 47 |
+
return await e.eor(
|
| 48 |
+
get_string("help_2").format(HNDLR),
|
| 49 |
+
)
|
| 50 |
+
except BotInlineDisabledError:
|
| 51 |
+
return await e.eor(get_string("help_3"))
|
| 52 |
+
await results[0].click(e.chat_id, reply_to=e.reply_to_msg_id, hide_via=True)
|
| 53 |
+
return await e.delete()
|
| 54 |
+
await e.eor(get_string("wspr_3"))
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
@in_pattern("wspr", owner=True)
|
| 58 |
+
async def _(e):
|
| 59 |
+
iuser = e.query.user_id
|
| 60 |
+
zzz = e.text.split(maxsplit=2)
|
| 61 |
+
try:
|
| 62 |
+
query = zzz[1]
|
| 63 |
+
if query.isdigit():
|
| 64 |
+
query = int(query)
|
| 65 |
+
logi = await ultroid_bot.get_entity(query)
|
| 66 |
+
if not isinstance(logi, types.User):
|
| 67 |
+
raise ValueError("Invalid Username.")
|
| 68 |
+
except IndexError:
|
| 69 |
+
sur = await e.builder.article(
|
| 70 |
+
title="Give Username",
|
| 71 |
+
description="You Didn't Type Username or id.",
|
| 72 |
+
text="You Didn't Type Username or id.",
|
| 73 |
+
)
|
| 74 |
+
return await e.answer([sur])
|
| 75 |
+
except ValueError as er:
|
| 76 |
+
LOGS.exception(er)
|
| 77 |
+
sur = await e.builder.article(
|
| 78 |
+
title="User Not Found",
|
| 79 |
+
description="Make sure username or id is correct.",
|
| 80 |
+
text="Make sure username or id is correct.",
|
| 81 |
+
)
|
| 82 |
+
return await e.answer([sur])
|
| 83 |
+
try:
|
| 84 |
+
desc = zzz[2]
|
| 85 |
+
except IndexError:
|
| 86 |
+
sur = await e.builder.article(
|
| 87 |
+
title="Type ur msg", text="You Didn't Type Your Msg"
|
| 88 |
+
)
|
| 89 |
+
return await e.answer([sur])
|
| 90 |
+
button = [
|
| 91 |
+
[
|
| 92 |
+
Button.inline("Secret Msg", data=f"dd_{e.id}"),
|
| 93 |
+
Button.inline("Delete Msg", data=f"del_{e.id}"),
|
| 94 |
+
],
|
| 95 |
+
[
|
| 96 |
+
Button.switch_inline(
|
| 97 |
+
"New", query=f"wspr {logi.username or logi.id}", same_peer=True
|
| 98 |
+
)
|
| 99 |
+
],
|
| 100 |
+
]
|
| 101 |
+
us = logi.username or logi.first_name
|
| 102 |
+
sur = await e.builder.article(
|
| 103 |
+
title=logi.first_name,
|
| 104 |
+
description=desc,
|
| 105 |
+
text=get_string("wspr_1").format(us),
|
| 106 |
+
buttons=button,
|
| 107 |
+
)
|
| 108 |
+
buddhhu.update({e.id: [logi.id, iuser, desc]})
|
| 109 |
+
await e.answer([sur])
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
@in_pattern("msg", owner=True)
|
| 113 |
+
async def _(e):
|
| 114 |
+
zzz = e.text.split(maxsplit=1)
|
| 115 |
+
desc = "Touch me"
|
| 116 |
+
try:
|
| 117 |
+
query = zzz[1]
|
| 118 |
+
if query.isdigit():
|
| 119 |
+
query = int(query)
|
| 120 |
+
logi = await ultroid_bot(gu(id=query))
|
| 121 |
+
user = logi.users[0]
|
| 122 |
+
mention = inline_mention(user)
|
| 123 |
+
x = user.status
|
| 124 |
+
if isinstance(x, types.UserStatusOnline):
|
| 125 |
+
status = "Online"
|
| 126 |
+
elif isinstance(x, types.UserStatusOffline):
|
| 127 |
+
status = "Offline"
|
| 128 |
+
elif isinstance(x, types.UserStatusRecently):
|
| 129 |
+
status = "Last Seen Recently"
|
| 130 |
+
elif isinstance(x, types.UserStatusLastMonth):
|
| 131 |
+
status = "Last seen months ago"
|
| 132 |
+
elif isinstance(x, types.UserStatusLastWeek):
|
| 133 |
+
status = "Last seen weeks ago"
|
| 134 |
+
else:
|
| 135 |
+
status = "Can't Tell"
|
| 136 |
+
text = f"**Name:** `{user.first_name}`\n"
|
| 137 |
+
text += f"**Id:** `{user.id}`\n"
|
| 138 |
+
if user.username:
|
| 139 |
+
text += f"**Username:** `{user.username}`\n"
|
| 140 |
+
url = f"https://t.me/{user.username}"
|
| 141 |
+
else:
|
| 142 |
+
text += f"**Mention:** `{mention}`\n"
|
| 143 |
+
url = f"tg://user?id={user.id}"
|
| 144 |
+
text += f"**Status:** `{status}`\n"
|
| 145 |
+
text += f"**About:** `{logi.full_user.about}`"
|
| 146 |
+
button = [
|
| 147 |
+
Button.url("Private", url=url),
|
| 148 |
+
Button.switch_inline(
|
| 149 |
+
"Secret msg",
|
| 150 |
+
query=f"wspr {query} Hello 👋",
|
| 151 |
+
same_peer=True,
|
| 152 |
+
),
|
| 153 |
+
]
|
| 154 |
+
sur = e.builder.article(
|
| 155 |
+
title=user.first_name,
|
| 156 |
+
description=desc,
|
| 157 |
+
text=text,
|
| 158 |
+
buttons=button,
|
| 159 |
+
)
|
| 160 |
+
except IndexError:
|
| 161 |
+
sur = e.builder.article(
|
| 162 |
+
title="Give Username",
|
| 163 |
+
description="You Didn't Type Username or id.",
|
| 164 |
+
text="You Didn't Type Username or id.",
|
| 165 |
+
)
|
| 166 |
+
except BaseException as er:
|
| 167 |
+
LOGS.exception(er)
|
| 168 |
+
name = get_string("wspr_4").format(query)
|
| 169 |
+
sur = e.builder.article(
|
| 170 |
+
title=name,
|
| 171 |
+
text=name,
|
| 172 |
+
)
|
| 173 |
+
|
| 174 |
+
await e.answer([sur])
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
@callback(
|
| 178 |
+
re.compile(
|
| 179 |
+
"dd_(.*)",
|
| 180 |
+
),
|
| 181 |
+
)
|
| 182 |
+
async def _(e):
|
| 183 |
+
ids = int(e.pattern_match.group(1).strip().decode("UTF-8"))
|
| 184 |
+
if buddhhu.get(ids):
|
| 185 |
+
if e.sender_id in buddhhu[ids]:
|
| 186 |
+
await e.answer(buddhhu[ids][-1], alert=True)
|
| 187 |
+
else:
|
| 188 |
+
await e.answer("Not For You", alert=True)
|
| 189 |
+
else:
|
| 190 |
+
await e.answer(get_string("wspr_2"), alert=True)
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
@callback(re.compile("del_(.*)"))
|
| 194 |
+
async def _(e):
|
| 195 |
+
ids = int(e.pattern_match.group(1).strip().decode("UTF-8"))
|
| 196 |
+
if buddhhu.get(ids):
|
| 197 |
+
if e.sender_id in buddhhu[ids]:
|
| 198 |
+
buddhhu.pop(ids)
|
| 199 |
+
try:
|
| 200 |
+
await e.edit(get_string("wspr_2"))
|
| 201 |
+
except MessageNotModifiedError:
|
| 202 |
+
pass
|
| 203 |
+
else:
|
| 204 |
+
await e.answer(get_string("wspr_5"), alert=True)
|
plugins/admintools.py
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_admintools")
|
| 11 |
+
|
| 12 |
+
import asyncio
|
| 13 |
+
|
| 14 |
+
from telethon.errors import BadRequestError
|
| 15 |
+
from telethon.errors.rpcerrorlist import ChatNotModifiedError, UserIdInvalidError
|
| 16 |
+
from telethon.tl.functions.channels import EditAdminRequest, GetFullChannelRequest
|
| 17 |
+
from telethon.tl.functions.messages import GetFullChatRequest, SetHistoryTTLRequest
|
| 18 |
+
from telethon.tl.types import InputMessagesFilterPinned
|
| 19 |
+
from telethon.utils import get_display_name
|
| 20 |
+
|
| 21 |
+
from pyUltroid.dB import DEVLIST
|
| 22 |
+
from pyUltroid.fns.admins import ban_time
|
| 23 |
+
from pyUltroid.fns.info import get_uinfo
|
| 24 |
+
|
| 25 |
+
from . import HNDLR, LOGS, eod, eor, get_string, inline_mention, types, ultroid_cmd
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@ultroid_cmd(
|
| 29 |
+
pattern="promote( (.*)|$)",
|
| 30 |
+
admins_only=True,
|
| 31 |
+
manager=True,
|
| 32 |
+
require="add_admins",
|
| 33 |
+
fullsudo=True,
|
| 34 |
+
)
|
| 35 |
+
async def prmte(ult):
|
| 36 |
+
xx = await ult.eor(get_string("com_1"))
|
| 37 |
+
user, rank = await get_uinfo(ult)
|
| 38 |
+
rank = rank or "Admin"
|
| 39 |
+
FullRight = False
|
| 40 |
+
if not user:
|
| 41 |
+
return await xx.edit(get_string("pro_1"))
|
| 42 |
+
if rank.split()[0] == "-f":
|
| 43 |
+
try:
|
| 44 |
+
rank = rank.split(maxsplit=1)[1]
|
| 45 |
+
except IndexError:
|
| 46 |
+
rank = "Admin"
|
| 47 |
+
FullRight = True
|
| 48 |
+
try:
|
| 49 |
+
if FullRight:
|
| 50 |
+
await ult.client(
|
| 51 |
+
EditAdminRequest(ult.chat_id, user.id, ult.chat.admin_rights, rank)
|
| 52 |
+
)
|
| 53 |
+
else:
|
| 54 |
+
await ult.client.edit_admin(
|
| 55 |
+
ult.chat_id,
|
| 56 |
+
user.id,
|
| 57 |
+
invite_users=True,
|
| 58 |
+
ban_users=True,
|
| 59 |
+
delete_messages=True,
|
| 60 |
+
pin_messages=True,
|
| 61 |
+
manage_call=True,
|
| 62 |
+
title=rank,
|
| 63 |
+
)
|
| 64 |
+
await eod(
|
| 65 |
+
xx, get_string("pro_2").format(inline_mention(user), ult.chat.title, rank)
|
| 66 |
+
)
|
| 67 |
+
except Exception as ex:
|
| 68 |
+
return await xx.edit(f"`{ex}`")
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
@ultroid_cmd(
|
| 72 |
+
pattern="demote( (.*)|$)",
|
| 73 |
+
admins_only=True,
|
| 74 |
+
manager=True,
|
| 75 |
+
require="add_admins",
|
| 76 |
+
fullsudo=True,
|
| 77 |
+
)
|
| 78 |
+
async def dmote(ult):
|
| 79 |
+
xx = await ult.eor(get_string("com_1"))
|
| 80 |
+
user, rank = await get_uinfo(ult)
|
| 81 |
+
if not rank:
|
| 82 |
+
rank = "Not Admin"
|
| 83 |
+
if not user:
|
| 84 |
+
return await xx.edit(get_string("de_1"))
|
| 85 |
+
try:
|
| 86 |
+
await ult.client.edit_admin(
|
| 87 |
+
ult.chat_id,
|
| 88 |
+
user.id,
|
| 89 |
+
invite_users=None,
|
| 90 |
+
ban_users=None,
|
| 91 |
+
delete_messages=None,
|
| 92 |
+
pin_messages=None,
|
| 93 |
+
manage_call=None,
|
| 94 |
+
title=rank,
|
| 95 |
+
)
|
| 96 |
+
await eod(xx, get_string("de_2").format(inline_mention(user), ult.chat.title))
|
| 97 |
+
except Exception as ex:
|
| 98 |
+
return await xx.edit(f"`{ex}`")
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
@ultroid_cmd(
|
| 102 |
+
pattern="ban( (.*)|$)",
|
| 103 |
+
admins_only=True,
|
| 104 |
+
manager=True,
|
| 105 |
+
require="ban_users",
|
| 106 |
+
fullsudo=True,
|
| 107 |
+
)
|
| 108 |
+
async def bban(ult):
|
| 109 |
+
something = await get_uinfo(ult)
|
| 110 |
+
if not something:
|
| 111 |
+
return
|
| 112 |
+
user, reason = something
|
| 113 |
+
if not user:
|
| 114 |
+
return await eod(ult, get_string("ban_1"))
|
| 115 |
+
if user.id in DEVLIST:
|
| 116 |
+
return await eod(ult, get_string("ban_2"))
|
| 117 |
+
try:
|
| 118 |
+
await ult.client.edit_permissions(ult.chat_id, user.id, view_messages=False)
|
| 119 |
+
except UserIdInvalidError:
|
| 120 |
+
return await eod(ult, get_string("adm_1"))
|
| 121 |
+
except BadRequestError:
|
| 122 |
+
return await eod(ult, get_string("ban_3"))
|
| 123 |
+
senderme = inline_mention(await ult.get_sender())
|
| 124 |
+
userme = inline_mention(user)
|
| 125 |
+
text = get_string("ban_4").format(userme, senderme, ult.chat.title)
|
| 126 |
+
if reason:
|
| 127 |
+
text += get_string("ban_5").format(reason)
|
| 128 |
+
await eod(ult, text)
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
@ultroid_cmd(
|
| 132 |
+
pattern="unban( (.*)|$)",
|
| 133 |
+
admins_only=True,
|
| 134 |
+
manager=True,
|
| 135 |
+
require="ban_users",
|
| 136 |
+
fullsudo=True,
|
| 137 |
+
)
|
| 138 |
+
async def uunban(ult):
|
| 139 |
+
xx = await ult.eor(get_string("com_1"))
|
| 140 |
+
if ult.text[1:].startswith("unbanall"):
|
| 141 |
+
return
|
| 142 |
+
something = await get_uinfo(ult)
|
| 143 |
+
if not something:
|
| 144 |
+
return
|
| 145 |
+
user, reason = something
|
| 146 |
+
if not user:
|
| 147 |
+
return await xx.edit(get_string("unban_1"))
|
| 148 |
+
try:
|
| 149 |
+
await ult.client.edit_permissions(ult.chat_id, user.id, view_messages=True)
|
| 150 |
+
except UserIdInvalidError:
|
| 151 |
+
return await eod(ult, get_string("adm_1"))
|
| 152 |
+
except BadRequestError:
|
| 153 |
+
return await xx.edit(get_string("adm_2"))
|
| 154 |
+
sender = inline_mention(await ult.get_sender())
|
| 155 |
+
text = get_string("unban_3").format(inline_mention(user), sender, ult.chat.title)
|
| 156 |
+
if reason:
|
| 157 |
+
text += get_string("ban_5").format(reason)
|
| 158 |
+
await xx.edit(text)
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
@ultroid_cmd(
|
| 162 |
+
pattern="kick( (.*)|$)",
|
| 163 |
+
manager=True,
|
| 164 |
+
require="ban_users",
|
| 165 |
+
fullsudo=True,
|
| 166 |
+
)
|
| 167 |
+
async def kck(ult):
|
| 168 |
+
if "kickme" in ult.text:
|
| 169 |
+
return
|
| 170 |
+
if ult.is_private:
|
| 171 |
+
return await ult.eor("`Use this in Group/Channel.`", time=5)
|
| 172 |
+
ml = ult.text.split(" ", maxsplit=1)[0]
|
| 173 |
+
xx = await ult.eor(get_string("com_1"))
|
| 174 |
+
something = await get_uinfo(ult)
|
| 175 |
+
if not something:
|
| 176 |
+
return
|
| 177 |
+
user, reason = something
|
| 178 |
+
if not user:
|
| 179 |
+
return await xx.edit(get_string("adm_1"))
|
| 180 |
+
if user.id in DEVLIST:
|
| 181 |
+
return await xx.edit(get_string("kick_2"))
|
| 182 |
+
if getattr(user, "is_self", False):
|
| 183 |
+
return await xx.edit(get_string("kick_3"))
|
| 184 |
+
try:
|
| 185 |
+
await ult.client.kick_participant(ult.chat_id, user.id)
|
| 186 |
+
except BadRequestError as er:
|
| 187 |
+
LOGS.info(er)
|
| 188 |
+
return await xx.edit(get_string("kick_1"))
|
| 189 |
+
except Exception as e:
|
| 190 |
+
LOGS.exception(e)
|
| 191 |
+
return
|
| 192 |
+
text = get_string("kick_4").format(
|
| 193 |
+
inline_mention(user), inline_mention(await ult.get_sender()), ult.chat.title
|
| 194 |
+
)
|
| 195 |
+
if reason:
|
| 196 |
+
text += get_string("ban_5").format(reason)
|
| 197 |
+
await xx.edit(text)
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
@ultroid_cmd(
|
| 201 |
+
pattern="tban( (.*)|$)",
|
| 202 |
+
admins_only=True,
|
| 203 |
+
manager=True,
|
| 204 |
+
require="ban_users",
|
| 205 |
+
fullsudo=True,
|
| 206 |
+
)
|
| 207 |
+
async def tkicki(e):
|
| 208 |
+
huh = e.text.split()
|
| 209 |
+
inputt = None
|
| 210 |
+
try:
|
| 211 |
+
tme = huh[1]
|
| 212 |
+
except IndexError:
|
| 213 |
+
return await e.eor(get_string("adm_3"), time=15)
|
| 214 |
+
try:
|
| 215 |
+
inputt = huh[2]
|
| 216 |
+
except IndexError:
|
| 217 |
+
if e.reply_to_msg_id:
|
| 218 |
+
inputt = (await e.get_reply_message()).sender_id
|
| 219 |
+
if not inputt:
|
| 220 |
+
return await e.eor(get_string("tban_1"))
|
| 221 |
+
userid = await e.client.parse_id(inputt)
|
| 222 |
+
try:
|
| 223 |
+
user = await e.client.get_entity(userid)
|
| 224 |
+
except Exception as ex:
|
| 225 |
+
return await eor(e, f"`{ex}`")
|
| 226 |
+
try:
|
| 227 |
+
bun = ban_time(tme)
|
| 228 |
+
await e.client.edit_permissions(
|
| 229 |
+
e.chat_id, user.id, until_date=bun, view_messages=False
|
| 230 |
+
)
|
| 231 |
+
await eod(
|
| 232 |
+
e,
|
| 233 |
+
get_string("tban_2").format(inline_mention(user), e.chat.title, tme),
|
| 234 |
+
time=15,
|
| 235 |
+
)
|
| 236 |
+
except Exception as m:
|
| 237 |
+
return await e.eor(str(m))
|
| 238 |
+
|
| 239 |
+
|
| 240 |
+
@ultroid_cmd(pattern="pin$", manager=True, require="pin_messages", fullsudo=True)
|
| 241 |
+
async def pin(msg):
|
| 242 |
+
if not msg.is_reply:
|
| 243 |
+
return await eor(msg, get_string("pin_1"))
|
| 244 |
+
me = await msg.get_reply_message()
|
| 245 |
+
if me.is_private:
|
| 246 |
+
text = "`Pinned.`"
|
| 247 |
+
else:
|
| 248 |
+
text = f"Pinned [This Message]({me.message_link}) !"
|
| 249 |
+
try:
|
| 250 |
+
await msg.client.pin_message(msg.chat_id, me.id, notify=False)
|
| 251 |
+
except BadRequestError:
|
| 252 |
+
return await eor(msg, get_string("adm_2"))
|
| 253 |
+
except Exception as e:
|
| 254 |
+
return await eor(msg, f"**ERROR:**`{e}`")
|
| 255 |
+
await eor(msg, text)
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
@ultroid_cmd(
|
| 259 |
+
pattern="unpin($| (.*))",
|
| 260 |
+
manager=True,
|
| 261 |
+
require="pin_messages",
|
| 262 |
+
fullsudo=True,
|
| 263 |
+
)
|
| 264 |
+
async def unp(ult):
|
| 265 |
+
xx = await ult.eor(get_string("com_1"))
|
| 266 |
+
ch = (ult.pattern_match.group(1).strip()).strip()
|
| 267 |
+
msg = None
|
| 268 |
+
if ult.is_reply:
|
| 269 |
+
msg = ult.reply_to_msg_id
|
| 270 |
+
elif ch != "all":
|
| 271 |
+
return await xx.edit(get_string("unpin_1").format(HNDLR))
|
| 272 |
+
try:
|
| 273 |
+
await ult.client.unpin_message(ult.chat_id, msg)
|
| 274 |
+
except BadRequestError:
|
| 275 |
+
return await xx.edit(get_string("adm_2"))
|
| 276 |
+
except Exception as e:
|
| 277 |
+
return await xx.edit(f"**ERROR:**`{e}`")
|
| 278 |
+
await xx.edit("`Unpinned!`")
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
@ultroid_cmd(
|
| 282 |
+
pattern="tpin( (.*)|$)",
|
| 283 |
+
admins_only=True,
|
| 284 |
+
manager=True,
|
| 285 |
+
require="pin_messages",
|
| 286 |
+
fullsudo=True,
|
| 287 |
+
)
|
| 288 |
+
async def pin_message(ult):
|
| 289 |
+
match = ult.pattern_match.group(1).strip()
|
| 290 |
+
if not ult.is_reply:
|
| 291 |
+
return await ult.eor("`Reply to message..`", time=6)
|
| 292 |
+
if not match:
|
| 293 |
+
return await ult.eor("`Please provide time..`", time=8)
|
| 294 |
+
msg = await ult.eor(get_string("com_1"))
|
| 295 |
+
msg_id = ult.reply_to_msg_id
|
| 296 |
+
try:
|
| 297 |
+
time = ban_time(match)
|
| 298 |
+
await ult.client.pin_message(ult.chat_id, msg_id)
|
| 299 |
+
await msg.eor(f"`pinned for time` `{time}`", time=8)
|
| 300 |
+
except Exception as er:
|
| 301 |
+
return await msg.edit(str(er))
|
| 302 |
+
await asyncio.sleep(time)
|
| 303 |
+
try:
|
| 304 |
+
await ult.client.unpin_message(ult.chat_id, msg_id)
|
| 305 |
+
except Exception as er:
|
| 306 |
+
LOGS.exception(er)
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
@ultroid_cmd(pattern="purge( (.*)|$)", manager=True, require="delete_messages")
|
| 310 |
+
async def fastpurger(purg):
|
| 311 |
+
match = purg.pattern_match.group(1).strip()
|
| 312 |
+
try:
|
| 313 |
+
ABC = purg.text[6]
|
| 314 |
+
except IndexError:
|
| 315 |
+
ABC = None
|
| 316 |
+
if ABC and purg.text[6] in ["m", "a"]:
|
| 317 |
+
return
|
| 318 |
+
if not purg._client._bot and (
|
| 319 |
+
(match)
|
| 320 |
+
or (purg.is_reply and (purg.is_private or isinstance(purg.chat, types.Chat)))
|
| 321 |
+
):
|
| 322 |
+
p = 0
|
| 323 |
+
async for msg in purg.client.iter_messages(
|
| 324 |
+
purg.chat_id,
|
| 325 |
+
limit=int(match) if match else None,
|
| 326 |
+
min_id=purg.reply_to_msg_id if purg.is_reply else None,
|
| 327 |
+
):
|
| 328 |
+
await msg.delete()
|
| 329 |
+
p += 0
|
| 330 |
+
return await eor(purg, f"Purged {p} Messages! ", time=5)
|
| 331 |
+
if not purg.reply_to_msg_id:
|
| 332 |
+
return await eor(purg, get_string("purge_1"), time=10)
|
| 333 |
+
try:
|
| 334 |
+
await purg.client.delete_messages(
|
| 335 |
+
purg.chat_id, list(range(purg.reply_to_msg_id, purg.id))
|
| 336 |
+
)
|
| 337 |
+
|
| 338 |
+
except Exception as er:
|
| 339 |
+
LOGS.info(er)
|
| 340 |
+
await purg.eor("__Fast purge complete!__", time=5)
|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
@ultroid_cmd(
|
| 344 |
+
pattern="purgeme( (.*)|$)",
|
| 345 |
+
)
|
| 346 |
+
async def fastpurgerme(purg):
|
| 347 |
+
if num := purg.pattern_match.group(1).strip():
|
| 348 |
+
try:
|
| 349 |
+
nnt = int(num)
|
| 350 |
+
except BaseException:
|
| 351 |
+
await eor(purg, get_string("com_3"), time=5)
|
| 352 |
+
return
|
| 353 |
+
mp = 0
|
| 354 |
+
async for mm in purg.client.iter_messages(
|
| 355 |
+
purg.chat_id, limit=nnt, from_user="me"
|
| 356 |
+
):
|
| 357 |
+
await mm.delete()
|
| 358 |
+
mp += 1
|
| 359 |
+
await eor(purg, f"Purged {mp} Messages!", time=5)
|
| 360 |
+
return
|
| 361 |
+
elif not purg.reply_to_msg_id:
|
| 362 |
+
return await eod(
|
| 363 |
+
purg,
|
| 364 |
+
"`Reply to a message to purge from or use it like ``purgeme <num>`",
|
| 365 |
+
time=10,
|
| 366 |
+
)
|
| 367 |
+
chat = await purg.get_input_chat()
|
| 368 |
+
msgs = []
|
| 369 |
+
async for msg in purg.client.iter_messages(
|
| 370 |
+
chat,
|
| 371 |
+
from_user="me",
|
| 372 |
+
min_id=purg.reply_to_msg_id,
|
| 373 |
+
):
|
| 374 |
+
msgs.append(msg)
|
| 375 |
+
if msgs:
|
| 376 |
+
await purg.client.delete_messages(chat, msgs)
|
| 377 |
+
await purg.eor(
|
| 378 |
+
"__Fast purge complete!__\n**Purged** `" + str(len(msgs)) + "` **messages.**",
|
| 379 |
+
time=5,
|
| 380 |
+
)
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
@ultroid_cmd(
|
| 384 |
+
pattern="purgeall$",
|
| 385 |
+
)
|
| 386 |
+
async def _(e):
|
| 387 |
+
if not e.is_reply:
|
| 388 |
+
return await eod(
|
| 389 |
+
e,
|
| 390 |
+
get_string("purgeall_1"),
|
| 391 |
+
)
|
| 392 |
+
|
| 393 |
+
msg = await e.get_reply_message()
|
| 394 |
+
name = msg.sender
|
| 395 |
+
try:
|
| 396 |
+
await e.client.delete_messages(e.chat_id, from_user=msg.sender_id)
|
| 397 |
+
await e.eor(get_string("purgeall_2").format(name.first_name), time=5)
|
| 398 |
+
except Exception as er:
|
| 399 |
+
return await e.eor(str(er), time=5)
|
| 400 |
+
|
| 401 |
+
@ultroid_cmd(pattern="pinned", manager=True, groups_only=True)
|
| 402 |
+
async def djshsh(event):
|
| 403 |
+
chat = await event.get_chat()
|
| 404 |
+
if isinstance(chat, types.Chat):
|
| 405 |
+
FChat = await event.client(GetFullChatRequest(chat.id))
|
| 406 |
+
elif isinstance(chat, types.Channel):
|
| 407 |
+
FChat = await event.client(GetFullChannelRequest(chat.id))
|
| 408 |
+
else:
|
| 409 |
+
return
|
| 410 |
+
msg_id = FChat.full_chat.pinned_msg_id
|
| 411 |
+
if not msg_id:
|
| 412 |
+
return await event.eor(get_string("pinned_1"))
|
| 413 |
+
msg = await event.client.get_messages(chat.id, ids=msg_id)
|
| 414 |
+
if msg:
|
| 415 |
+
await event.eor(get_string("pinned_2").format(msg.message_link))
|
| 416 |
+
|
| 417 |
+
|
| 418 |
+
@ultroid_cmd(
|
| 419 |
+
pattern="listpinned$",
|
| 420 |
+
)
|
| 421 |
+
async def get_all_pinned(event):
|
| 422 |
+
x = await event.eor(get_string("com_1"))
|
| 423 |
+
chat_id = (str(event.chat_id)).replace("-100", "")
|
| 424 |
+
chat_name = get_display_name(event.chat)
|
| 425 |
+
a = ""
|
| 426 |
+
c = 1
|
| 427 |
+
async for i in event.client.iter_messages(
|
| 428 |
+
event.chat_id, filter=InputMessagesFilterPinned
|
| 429 |
+
):
|
| 430 |
+
if i.message:
|
| 431 |
+
t = " ".join(i.message.split()[:4])
|
| 432 |
+
txt = f"{t}...."
|
| 433 |
+
else:
|
| 434 |
+
txt = "Go to message."
|
| 435 |
+
a += f"{c}. <a href=https://t.me/c/{chat_id}/{i.id}>{txt}</a>\n"
|
| 436 |
+
c += 1
|
| 437 |
+
|
| 438 |
+
if c == 1:
|
| 439 |
+
m = f"<b>The pinned message in {chat_name}:</b>\n\n"
|
| 440 |
+
else:
|
| 441 |
+
m = f"<b>List of pinned message(s) in {chat_name}:</b>\n\n"
|
| 442 |
+
|
| 443 |
+
if not a:
|
| 444 |
+
return await eor(x, get_string("listpin_1"), time=5)
|
| 445 |
+
|
| 446 |
+
await x.edit(m + a, parse_mode="html")
|
| 447 |
+
|
| 448 |
+
|
| 449 |
+
@ultroid_cmd(
|
| 450 |
+
pattern="autodelete( (.*)|$)",
|
| 451 |
+
admins_only=True,
|
| 452 |
+
)
|
| 453 |
+
async def autodelte(ult):
|
| 454 |
+
match = ult.pattern_match.group(1).strip()
|
| 455 |
+
if not match or match not in ["24h", "7d", "1m", "off"]:
|
| 456 |
+
return await ult.eor("`Please Use in Proper Format..`", time=5)
|
| 457 |
+
if match == "24h":
|
| 458 |
+
tt = 3600 * 24
|
| 459 |
+
elif match == "7d":
|
| 460 |
+
tt = 3600 * 24 * 7
|
| 461 |
+
elif match == "1m":
|
| 462 |
+
tt = 3600 * 24 * 31
|
| 463 |
+
else:
|
| 464 |
+
tt = 0
|
| 465 |
+
try:
|
| 466 |
+
await ult.client(SetHistoryTTLRequest(ult.chat_id, period=tt))
|
| 467 |
+
except ChatNotModifiedError:
|
| 468 |
+
return await ult.eor(
|
| 469 |
+
f"Auto Delete Setting is Already same to `{match}`", time=5
|
| 470 |
+
)
|
| 471 |
+
await ult.eor(f"Auto Delete Status Changed to `{match}` !")
|
plugins/afk.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_afk")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
import asyncio
|
| 14 |
+
|
| 15 |
+
from telethon import events
|
| 16 |
+
|
| 17 |
+
from pyUltroid.dB.afk_db import add_afk, del_afk, is_afk
|
| 18 |
+
from pyUltroid.dB.base import KeyManager
|
| 19 |
+
|
| 20 |
+
from . import (
|
| 21 |
+
LOG_CHANNEL,
|
| 22 |
+
NOSPAM_CHAT,
|
| 23 |
+
Redis,
|
| 24 |
+
asst,
|
| 25 |
+
get_string,
|
| 26 |
+
mediainfo,
|
| 27 |
+
udB,
|
| 28 |
+
ultroid_bot,
|
| 29 |
+
ultroid_cmd,
|
| 30 |
+
upload_file
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
old_afk_msg = []
|
| 34 |
+
|
| 35 |
+
is_approved = KeyManager("PMPERMIT", cast=list).contains
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@ultroid_cmd(pattern="afk( (.*)|$)", owner_only=True)
|
| 39 |
+
async def set_afk(event):
|
| 40 |
+
if event.client._bot or is_afk():
|
| 41 |
+
return
|
| 42 |
+
text, media, media_type = None, None, None
|
| 43 |
+
if event.pattern_match.group(1).strip():
|
| 44 |
+
text = event.text.split(maxsplit=1)[1]
|
| 45 |
+
reply = await event.get_reply_message()
|
| 46 |
+
if reply:
|
| 47 |
+
if reply.text and not text:
|
| 48 |
+
text = reply.text
|
| 49 |
+
if reply.media:
|
| 50 |
+
media_type = mediainfo(reply.media)
|
| 51 |
+
if media_type.startswith(("pic", "gif")):
|
| 52 |
+
file = await event.client.download_media(reply.media)
|
| 53 |
+
media = upload_file(file)
|
| 54 |
+
else:
|
| 55 |
+
media = reply.file.id
|
| 56 |
+
await event.eor("`Done`", time=2)
|
| 57 |
+
add_afk(text, media_type, media)
|
| 58 |
+
ultroid_bot.add_handler(remove_afk, events.NewMessage(outgoing=True))
|
| 59 |
+
ultroid_bot.add_handler(
|
| 60 |
+
on_afk,
|
| 61 |
+
events.NewMessage(
|
| 62 |
+
incoming=True, func=lambda e: bool(e.mentioned or e.is_private)
|
| 63 |
+
),
|
| 64 |
+
)
|
| 65 |
+
msg1, msg2 = None, None
|
| 66 |
+
if text and media:
|
| 67 |
+
if "sticker" in media_type:
|
| 68 |
+
msg1 = await ultroid_bot.send_file(event.chat_id, file=media)
|
| 69 |
+
msg2 = await ultroid_bot.send_message(
|
| 70 |
+
event.chat_id, get_string("afk_5").format(text)
|
| 71 |
+
)
|
| 72 |
+
else:
|
| 73 |
+
msg1 = await ultroid_bot.send_message(
|
| 74 |
+
event.chat_id, get_string("afk_5").format(text), file=media
|
| 75 |
+
)
|
| 76 |
+
elif media:
|
| 77 |
+
if "sticker" in media_type:
|
| 78 |
+
msg1 = await ultroid_bot.send_file(event.chat_id, file=media)
|
| 79 |
+
msg2 = await ultroid_bot.send_message(event.chat_id, get_string("afk_6"))
|
| 80 |
+
else:
|
| 81 |
+
msg1 = await ultroid_bot.send_message(
|
| 82 |
+
event.chat_id, get_string("afk_6"), file=media
|
| 83 |
+
)
|
| 84 |
+
elif text:
|
| 85 |
+
msg1 = await event.respond(get_string("afk_5").format(text))
|
| 86 |
+
else:
|
| 87 |
+
msg1 = await event.respond(get_string("afk_6"))
|
| 88 |
+
old_afk_msg.append(msg1)
|
| 89 |
+
if msg2:
|
| 90 |
+
old_afk_msg.append(msg2)
|
| 91 |
+
return await asst.send_message(LOG_CHANNEL, msg2.text)
|
| 92 |
+
await asst.send_message(LOG_CHANNEL, msg1.text)
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
async def remove_afk(event):
|
| 96 |
+
if event.is_private and udB.get_key("PMSETTING") and not is_approved(event.chat_id):
|
| 97 |
+
return
|
| 98 |
+
elif "afk" in event.text.lower():
|
| 99 |
+
return
|
| 100 |
+
elif event.chat_id in NOSPAM_CHAT:
|
| 101 |
+
return
|
| 102 |
+
if is_afk():
|
| 103 |
+
_, _, _, afk_time = is_afk()
|
| 104 |
+
del_afk()
|
| 105 |
+
off = await event.reply(get_string("afk_1").format(afk_time))
|
| 106 |
+
await asst.send_message(LOG_CHANNEL, get_string("afk_2").format(afk_time))
|
| 107 |
+
for x in old_afk_msg:
|
| 108 |
+
try:
|
| 109 |
+
await x.delete()
|
| 110 |
+
except BaseException:
|
| 111 |
+
pass
|
| 112 |
+
await asyncio.sleep(10)
|
| 113 |
+
await off.delete()
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
async def on_afk(event):
|
| 117 |
+
if event.is_private and Redis("PMSETTING") and not is_approved(event.chat_id):
|
| 118 |
+
return
|
| 119 |
+
elif "afk" in event.text.lower():
|
| 120 |
+
return
|
| 121 |
+
elif not is_afk():
|
| 122 |
+
return
|
| 123 |
+
if event.chat_id in NOSPAM_CHAT:
|
| 124 |
+
return
|
| 125 |
+
sender = await event.get_sender()
|
| 126 |
+
if sender.bot or sender.verified:
|
| 127 |
+
return
|
| 128 |
+
text, media_type, media, afk_time = is_afk()
|
| 129 |
+
msg1, msg2 = None, None
|
| 130 |
+
if text and media:
|
| 131 |
+
if "sticker" in media_type:
|
| 132 |
+
msg1 = await event.reply(file=media)
|
| 133 |
+
msg2 = await event.reply(get_string("afk_3").format(afk_time, text))
|
| 134 |
+
else:
|
| 135 |
+
msg1 = await event.reply(
|
| 136 |
+
get_string("afk_3").format(afk_time, text), file=media
|
| 137 |
+
)
|
| 138 |
+
elif media:
|
| 139 |
+
if "sticker" in media_type:
|
| 140 |
+
msg1 = await event.reply(file=media)
|
| 141 |
+
msg2 = await event.reply(get_string("afk_4").format(afk_time))
|
| 142 |
+
else:
|
| 143 |
+
msg1 = await event.reply(get_string("afk_4").format(afk_time), file=media)
|
| 144 |
+
elif text:
|
| 145 |
+
msg1 = await event.reply(get_string("afk_3").format(afk_time, text))
|
| 146 |
+
else:
|
| 147 |
+
msg1 = await event.reply(get_string("afk_4").format(afk_time))
|
| 148 |
+
for x in old_afk_msg:
|
| 149 |
+
try:
|
| 150 |
+
await x.delete()
|
| 151 |
+
except BaseException:
|
| 152 |
+
pass
|
| 153 |
+
old_afk_msg.append(msg1)
|
| 154 |
+
if msg2:
|
| 155 |
+
old_afk_msg.append(msg2)
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
if udB.get_key("AFK_DB"):
|
| 159 |
+
ultroid_bot.add_handler(remove_afk, events.NewMessage(outgoing=True))
|
| 160 |
+
ultroid_bot.add_handler(
|
| 161 |
+
on_afk,
|
| 162 |
+
events.NewMessage(
|
| 163 |
+
incoming=True, func=lambda e: bool(e.mentioned or e.is_private)
|
| 164 |
+
),
|
| 165 |
+
)
|
plugins/aiwrapper.py
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
"""
|
| 9 |
+
✘ Commands Available -
|
| 10 |
+
|
| 11 |
+
• `{i}gemini <prompt>`
|
| 12 |
+
Get response from Google Gemini.
|
| 13 |
+
|
| 14 |
+
• `{i}antr <prompt>`
|
| 15 |
+
Get response from Anthropic Claude.
|
| 16 |
+
|
| 17 |
+
• `{i}gpt <prompt>`
|
| 18 |
+
Get response from OpenAI GPT.
|
| 19 |
+
|
| 20 |
+
• `{i}deepseek <prompt>`
|
| 21 |
+
Get response from DeepSeek AI.
|
| 22 |
+
|
| 23 |
+
Set custom models using:
|
| 24 |
+
• OPENAI_MODEL: default: gpt-4o-mini
|
| 25 |
+
• ANTHROPIC_MODEL: claude-3-opus-20240229
|
| 26 |
+
• GEMINI_MODEL: gemini-1.5-flash
|
| 27 |
+
• DEEPSEEK_MODEL: deepseek-chat
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
import json
|
| 31 |
+
from . import LOGS, eor, get_string, udB, ultroid_cmd, async_searcher
|
| 32 |
+
import aiohttp
|
| 33 |
+
import asyncio
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
ENDPOINTS = {
|
| 37 |
+
"gpt": "https://api.openai.com/v1/chat/completions",
|
| 38 |
+
"antr": "https://api.anthropic.com/v1/messages",
|
| 39 |
+
"gemini": "https://generativelanguage.googleapis.com/v1beta/chat/completions",
|
| 40 |
+
"deepseek": "https://api.deepseek.com/chat/completions"
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
DEFAULT_MODELS = {
|
| 44 |
+
"gpt": "gpt-4o-mini",
|
| 45 |
+
"antr": "claude-3-opus-20240229",
|
| 46 |
+
"gemini": "gemini-1.5-flash",
|
| 47 |
+
"deepseek": "deepseek-chat"
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def get_model(provider):
|
| 52 |
+
"""Get model name from database or use default"""
|
| 53 |
+
model_keys = {
|
| 54 |
+
"gpt": "OPENAI_MODEL",
|
| 55 |
+
"antr": "ANTHROPIC_MODEL",
|
| 56 |
+
"gemini": "GEMINI_MODEL",
|
| 57 |
+
"deepseek": "DEEPSEEK_MODEL"
|
| 58 |
+
}
|
| 59 |
+
return udB.get_key(model_keys[provider]) or DEFAULT_MODELS[provider]
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
async def stream_response(msg, text):
|
| 63 |
+
"""Stream response by editing message"""
|
| 64 |
+
current = ""
|
| 65 |
+
# Split into chunks of ~100 characters at word boundaries
|
| 66 |
+
words = text.split()
|
| 67 |
+
chunks = []
|
| 68 |
+
current_chunk = []
|
| 69 |
+
|
| 70 |
+
for word in words:
|
| 71 |
+
current_chunk.append(word)
|
| 72 |
+
if len(" ".join(current_chunk)) > 100:
|
| 73 |
+
chunks.append(" ".join(current_chunk[:-1]))
|
| 74 |
+
current_chunk = [word]
|
| 75 |
+
if current_chunk:
|
| 76 |
+
chunks.append(" ".join(current_chunk))
|
| 77 |
+
|
| 78 |
+
for chunk in chunks:
|
| 79 |
+
current += chunk + " "
|
| 80 |
+
try:
|
| 81 |
+
await msg.edit(current)
|
| 82 |
+
except Exception:
|
| 83 |
+
pass
|
| 84 |
+
await asyncio.sleep(0.5)
|
| 85 |
+
return current
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
async def get_ai_response(provider, prompt, api_key, stream=False):
|
| 89 |
+
"""Get response from AI provider"""
|
| 90 |
+
try:
|
| 91 |
+
headers = {"Content-Type": "application/json"}
|
| 92 |
+
model = get_model(provider)
|
| 93 |
+
|
| 94 |
+
if provider == "gpt":
|
| 95 |
+
headers["Authorization"] = f"Bearer {api_key}"
|
| 96 |
+
data = {
|
| 97 |
+
"model": model,
|
| 98 |
+
"messages": [{"role": "user", "content": prompt}],
|
| 99 |
+
"stream": stream
|
| 100 |
+
}
|
| 101 |
+
if not stream:
|
| 102 |
+
response = await async_searcher(
|
| 103 |
+
ENDPOINTS[provider],
|
| 104 |
+
headers=headers,
|
| 105 |
+
post=True,
|
| 106 |
+
json=data,
|
| 107 |
+
re_json=True
|
| 108 |
+
)
|
| 109 |
+
yield response["choices"][0]["message"]["content"]
|
| 110 |
+
return
|
| 111 |
+
|
| 112 |
+
async with aiohttp.ClientSession() as session:
|
| 113 |
+
async with session.post(
|
| 114 |
+
ENDPOINTS[provider],
|
| 115 |
+
headers=headers,
|
| 116 |
+
json=data
|
| 117 |
+
) as resp:
|
| 118 |
+
async for line in resp.content:
|
| 119 |
+
if line:
|
| 120 |
+
try:
|
| 121 |
+
json_line = json.loads(line.decode('utf-8').strip().strip('data:').strip())
|
| 122 |
+
if 'choices' in json_line and json_line['choices']:
|
| 123 |
+
content = json_line['choices'][0].get('delta', {}).get('content', '')
|
| 124 |
+
if content:
|
| 125 |
+
yield content
|
| 126 |
+
except Exception:
|
| 127 |
+
continue
|
| 128 |
+
|
| 129 |
+
elif provider == "antr":
|
| 130 |
+
headers["x-api-key"] = api_key
|
| 131 |
+
headers["anthropic-version"] = "2023-06-01"
|
| 132 |
+
data = {
|
| 133 |
+
"model": model,
|
| 134 |
+
"messages": [{"role": "user", "content": prompt}],
|
| 135 |
+
"stream": stream
|
| 136 |
+
}
|
| 137 |
+
if not stream:
|
| 138 |
+
response = await async_searcher(
|
| 139 |
+
ENDPOINTS[provider],
|
| 140 |
+
headers=headers,
|
| 141 |
+
post=True,
|
| 142 |
+
json=data,
|
| 143 |
+
re_json=True
|
| 144 |
+
)
|
| 145 |
+
yield response["content"][0]["text"]
|
| 146 |
+
return
|
| 147 |
+
|
| 148 |
+
async with aiohttp.ClientSession() as session:
|
| 149 |
+
async with session.post(
|
| 150 |
+
ENDPOINTS[provider],
|
| 151 |
+
headers=headers,
|
| 152 |
+
json=data
|
| 153 |
+
) as resp:
|
| 154 |
+
async for line in resp.content:
|
| 155 |
+
if line:
|
| 156 |
+
try:
|
| 157 |
+
json_line = json.loads(line.decode('utf-8').strip())
|
| 158 |
+
if 'content' in json_line:
|
| 159 |
+
content = json_line['content'][0]['text']
|
| 160 |
+
if content:
|
| 161 |
+
yield content
|
| 162 |
+
except Exception:
|
| 163 |
+
continue
|
| 164 |
+
|
| 165 |
+
elif provider == "gemini":
|
| 166 |
+
headers["Authorization"] = f"Bearer {api_key}"
|
| 167 |
+
data = {
|
| 168 |
+
"model": model,
|
| 169 |
+
"messages": [
|
| 170 |
+
{"role": "system", "content": "You are a helpful assistant."},
|
| 171 |
+
{"role": "user", "content": prompt}
|
| 172 |
+
],
|
| 173 |
+
"stream": stream
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
if not stream:
|
| 177 |
+
try:
|
| 178 |
+
response = await async_searcher(
|
| 179 |
+
ENDPOINTS[provider],
|
| 180 |
+
headers=headers,
|
| 181 |
+
post=True,
|
| 182 |
+
json=data,
|
| 183 |
+
re_json=True
|
| 184 |
+
)
|
| 185 |
+
if "error" in response:
|
| 186 |
+
error = response["error"]
|
| 187 |
+
if error.get("code") == 429:
|
| 188 |
+
retry_delay = None
|
| 189 |
+
for detail in error.get("details", []):
|
| 190 |
+
if detail.get("@type") == "type.googleapis.com/google.rpc.RetryInfo":
|
| 191 |
+
retry_delay = detail.get("retryDelay", "60s").rstrip("s")
|
| 192 |
+
error_msg = f"⚠️ Rate limit exceeded. Please try again in {retry_delay} seconds."
|
| 193 |
+
if "free_tier" in str(error):
|
| 194 |
+
error_msg += "\nConsider upgrading to a paid tier for higher quotas."
|
| 195 |
+
yield error_msg
|
| 196 |
+
return
|
| 197 |
+
yield f"Error: {error.get('message', 'Unknown error occurred')}"
|
| 198 |
+
return
|
| 199 |
+
yield response["choices"][0]["message"]["content"]
|
| 200 |
+
except Exception as e:
|
| 201 |
+
LOGS.exception(e)
|
| 202 |
+
yield f"Error: {str(e)}"
|
| 203 |
+
return
|
| 204 |
+
|
| 205 |
+
async with aiohttp.ClientSession() as session:
|
| 206 |
+
try:
|
| 207 |
+
async with session.post(
|
| 208 |
+
ENDPOINTS[provider],
|
| 209 |
+
headers=headers,
|
| 210 |
+
json=data
|
| 211 |
+
) as resp:
|
| 212 |
+
if resp.status == 429:
|
| 213 |
+
error_data = await resp.json()
|
| 214 |
+
retry_delay = "60"
|
| 215 |
+
for detail in error_data.get("error", {}).get("details", []):
|
| 216 |
+
if detail.get("@type") == "type.googleapis.com/google.rpc.RetryInfo":
|
| 217 |
+
retry_delay = detail.get("retryDelay", "60s").rstrip("s")
|
| 218 |
+
yield f"⚠️ Rate limit exceeded. Please try again in {retry_delay} seconds."
|
| 219 |
+
return
|
| 220 |
+
|
| 221 |
+
if resp.status != 200:
|
| 222 |
+
error_data = await resp.json()
|
| 223 |
+
yield f"Error: {error_data.get('error', {}).get('message', 'Unknown error occurred')}"
|
| 224 |
+
return
|
| 225 |
+
|
| 226 |
+
async for line in resp.content:
|
| 227 |
+
if line:
|
| 228 |
+
text = line.decode('utf-8').strip()
|
| 229 |
+
if text.startswith('data: '):
|
| 230 |
+
data = text[6:] # Remove 'data: ' prefix
|
| 231 |
+
if data == '[DONE]':
|
| 232 |
+
break
|
| 233 |
+
try:
|
| 234 |
+
json_data = json.loads(data)
|
| 235 |
+
if 'choices' in json_data and json_data['choices']:
|
| 236 |
+
content = json_data['choices'][0].get('delta', {}).get('content', '')
|
| 237 |
+
if content:
|
| 238 |
+
yield content
|
| 239 |
+
except json.JSONDecodeError:
|
| 240 |
+
continue
|
| 241 |
+
except Exception as e:
|
| 242 |
+
LOGS.exception(e)
|
| 243 |
+
yield f"Error: {str(e)}"
|
| 244 |
+
|
| 245 |
+
elif provider == "deepseek":
|
| 246 |
+
headers["Authorization"] = f"Bearer {api_key}"
|
| 247 |
+
data = {
|
| 248 |
+
"model": model,
|
| 249 |
+
"messages": [{"role": "user", "content": prompt}],
|
| 250 |
+
"stream": stream
|
| 251 |
+
}
|
| 252 |
+
if not stream:
|
| 253 |
+
response = await async_searcher(
|
| 254 |
+
ENDPOINTS[provider],
|
| 255 |
+
headers=headers,
|
| 256 |
+
post=True,
|
| 257 |
+
json=data,
|
| 258 |
+
re_json=True
|
| 259 |
+
)
|
| 260 |
+
yield response["choices"][0]["message"]["content"]
|
| 261 |
+
return
|
| 262 |
+
|
| 263 |
+
async with aiohttp.ClientSession() as session:
|
| 264 |
+
async with session.post(
|
| 265 |
+
ENDPOINTS[provider],
|
| 266 |
+
headers=headers,
|
| 267 |
+
json=data
|
| 268 |
+
) as resp:
|
| 269 |
+
async for line in resp.content:
|
| 270 |
+
if line:
|
| 271 |
+
try:
|
| 272 |
+
json_line = json.loads(line.decode('utf-8').strip())
|
| 273 |
+
if 'choices' in json_line and json_line['choices']:
|
| 274 |
+
content = json_line['choices'][0].get('delta', {}).get('content', '')
|
| 275 |
+
if content:
|
| 276 |
+
yield content
|
| 277 |
+
except Exception:
|
| 278 |
+
continue
|
| 279 |
+
|
| 280 |
+
except Exception as e:
|
| 281 |
+
LOGS.exception(e)
|
| 282 |
+
yield f"Error: {str(e)}"
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
@ultroid_cmd(pattern="gemini( (.*)|$)")
|
| 286 |
+
async def gemini_ai(event):
|
| 287 |
+
"""Use Google Gemini"""
|
| 288 |
+
prompt = event.pattern_match.group(1).strip()
|
| 289 |
+
if not prompt:
|
| 290 |
+
return await event.eor("❌ Please provide a prompt!")
|
| 291 |
+
|
| 292 |
+
api_key = udB.get_key("GEMINI_API_KEY")
|
| 293 |
+
if not api_key:
|
| 294 |
+
return await event.eor("⚠️ Please set Gemini API key using `setdb GEMINI_API_KEY your_api_key`")
|
| 295 |
+
|
| 296 |
+
msg = await event.eor("🤔 Thinking...")
|
| 297 |
+
model = get_model("gemini")
|
| 298 |
+
|
| 299 |
+
header = (
|
| 300 |
+
"🤖 **Google Gemini**\n"
|
| 301 |
+
f"**Model:** `{model}`\n"
|
| 302 |
+
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
| 303 |
+
f"**🔍 Prompt:**\n{prompt}\n\n"
|
| 304 |
+
"**💡 Response:**\n"
|
| 305 |
+
)
|
| 306 |
+
|
| 307 |
+
if event.client.me.bot:
|
| 308 |
+
await msg.edit(header)
|
| 309 |
+
response = ""
|
| 310 |
+
async for chunk in get_ai_response("gemini", prompt, api_key, stream=True):
|
| 311 |
+
response += chunk
|
| 312 |
+
try:
|
| 313 |
+
await msg.edit(header + response)
|
| 314 |
+
except Exception:
|
| 315 |
+
pass
|
| 316 |
+
else:
|
| 317 |
+
response = ""
|
| 318 |
+
async for chunk in get_ai_response("gemini", prompt, api_key, stream=True):
|
| 319 |
+
response += chunk
|
| 320 |
+
try:
|
| 321 |
+
await msg.edit(header + response)
|
| 322 |
+
except Exception:
|
| 323 |
+
pass
|
| 324 |
+
|
| 325 |
+
@ultroid_cmd(pattern="antr( (.*)|$)")
|
| 326 |
+
async def anthropic_ai(event):
|
| 327 |
+
"""Use Anthropic Claude"""
|
| 328 |
+
prompt = event.pattern_match.group(1).strip()
|
| 329 |
+
if not prompt:
|
| 330 |
+
return await event.eor("❌ Please provide a prompt!")
|
| 331 |
+
|
| 332 |
+
api_key = udB.get_key("ANTHROPIC_KEY")
|
| 333 |
+
if not api_key:
|
| 334 |
+
return await event.eor("⚠️ Please set Anthropic API key using `setdb ANTHROPIC_KEY your_api_key`")
|
| 335 |
+
|
| 336 |
+
msg = await event.eor("🤔 Thinking...")
|
| 337 |
+
model = get_model("antr")
|
| 338 |
+
|
| 339 |
+
formatted_response = (
|
| 340 |
+
"🧠 **Anthropic Claude**\n"
|
| 341 |
+
f"**Model:** `{model}`\n"
|
| 342 |
+
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
| 343 |
+
f"**🔍 Prompt:**\n{prompt}\n\n"
|
| 344 |
+
f"**💡 Response:**\n"
|
| 345 |
+
)
|
| 346 |
+
|
| 347 |
+
if event.client.me.bot:
|
| 348 |
+
await msg.edit(formatted_response)
|
| 349 |
+
response = ""
|
| 350 |
+
async for chunk in get_ai_response("antr", prompt, api_key, stream=True):
|
| 351 |
+
response += chunk
|
| 352 |
+
try:
|
| 353 |
+
await msg.edit(formatted_response + response)
|
| 354 |
+
except Exception:
|
| 355 |
+
pass
|
| 356 |
+
else:
|
| 357 |
+
response = ""
|
| 358 |
+
async for chunk in get_ai_response("antr", prompt, api_key, stream=True):
|
| 359 |
+
response += chunk
|
| 360 |
+
try:
|
| 361 |
+
await msg.edit(formatted_response + response)
|
| 362 |
+
except Exception:
|
| 363 |
+
pass
|
| 364 |
+
|
| 365 |
+
@ultroid_cmd(pattern="gpt( (.*)|$)")
|
| 366 |
+
async def openai_ai(event):
|
| 367 |
+
"""Use OpenAI GPT"""
|
| 368 |
+
prompt = event.pattern_match.group(1).strip()
|
| 369 |
+
if not prompt:
|
| 370 |
+
return await event.eor("❌ Please provide a prompt!")
|
| 371 |
+
|
| 372 |
+
api_key = udB.get_key("OPENAI_API_KEY")
|
| 373 |
+
if not api_key:
|
| 374 |
+
return await event.eor("⚠️ Please set GPT API key using `setdb OPENAI_API_KEY your_api_key`")
|
| 375 |
+
|
| 376 |
+
msg = await event.eor("🤔 Thinking...")
|
| 377 |
+
model = get_model("gpt")
|
| 378 |
+
|
| 379 |
+
header = (
|
| 380 |
+
"🌟 **OpenAI GPT**\n"
|
| 381 |
+
f"**Model:** `{model}`\n"
|
| 382 |
+
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
| 383 |
+
f"**🔍 Prompt:**\n{prompt}\n\n"
|
| 384 |
+
"**💡 Response:**\n"
|
| 385 |
+
)
|
| 386 |
+
|
| 387 |
+
if event.client.me.bot:
|
| 388 |
+
await msg.edit(header)
|
| 389 |
+
response = ""
|
| 390 |
+
async for chunk in get_ai_response("gpt", prompt, api_key, stream=True):
|
| 391 |
+
response += chunk
|
| 392 |
+
try:
|
| 393 |
+
await msg.edit(header + response)
|
| 394 |
+
except Exception:
|
| 395 |
+
pass
|
| 396 |
+
else:
|
| 397 |
+
response =""
|
| 398 |
+
async for chunk in get_ai_response("gpt", prompt, api_key, stream=True):
|
| 399 |
+
response += chunk
|
| 400 |
+
try:
|
| 401 |
+
await msg.edit(header + response)
|
| 402 |
+
except Exception:
|
| 403 |
+
pass
|
| 404 |
+
|
| 405 |
+
@ultroid_cmd(pattern="deepseek( (.*)|$)")
|
| 406 |
+
async def deepseek_ai(event):
|
| 407 |
+
"""Use DeepSeek AI"""
|
| 408 |
+
prompt = event.pattern_match.group(1).strip()
|
| 409 |
+
if not prompt:
|
| 410 |
+
return await event.eor("❌ Please provide a prompt!")
|
| 411 |
+
|
| 412 |
+
api_key = udB.get_key("DEEPSEEK_API_KEY")
|
| 413 |
+
if not api_key:
|
| 414 |
+
return await event.eor("⚠️ Please set DeepSeek API key using `setdb DEEPSEEK_API_KEY your_api_key`")
|
| 415 |
+
|
| 416 |
+
msg = await event.eor("🤔 Thinking...")
|
| 417 |
+
model = get_model("deepseek")
|
| 418 |
+
|
| 419 |
+
formatted_response = (
|
| 420 |
+
"🤖 **DeepSeek AI**\n"
|
| 421 |
+
f"**Model:** `{model}`\n"
|
| 422 |
+
"➖➖➖➖➖➖➖➖➖➖\n\n"
|
| 423 |
+
f"**🔍 Prompt:**\n{prompt}\n\n"
|
| 424 |
+
f"**💡 Response:**\n"
|
| 425 |
+
)
|
| 426 |
+
|
| 427 |
+
if event.client.me.bot:
|
| 428 |
+
await msg.edit(formatted_response)
|
| 429 |
+
response = ""
|
| 430 |
+
async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True):
|
| 431 |
+
response += chunk
|
| 432 |
+
try:
|
| 433 |
+
await msg.edit(formatted_response + response)
|
| 434 |
+
except Exception:
|
| 435 |
+
pass
|
| 436 |
+
else:
|
| 437 |
+
response = ""
|
| 438 |
+
async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True):
|
| 439 |
+
response += chunk
|
| 440 |
+
|
| 441 |
+
try:
|
| 442 |
+
await msg.edit(formatted_response + response)
|
| 443 |
+
except Exception:
|
| 444 |
+
pass
|
| 445 |
+
|
plugins/antiflood.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_antiflood")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
import re
|
| 14 |
+
|
| 15 |
+
from telethon.events import NewMessage as NewMsg
|
| 16 |
+
|
| 17 |
+
from pyUltroid.dB import DEVLIST
|
| 18 |
+
from pyUltroid.dB.antiflood_db import get_flood, get_flood_limit, rem_flood, set_flood
|
| 19 |
+
from pyUltroid.fns.admins import admin_check
|
| 20 |
+
|
| 21 |
+
from . import Button, Redis, asst, callback, eod, get_string, ultroid_bot, ultroid_cmd
|
| 22 |
+
|
| 23 |
+
_check_flood = {}
|
| 24 |
+
|
| 25 |
+
if Redis("ANTIFLOOD"):
|
| 26 |
+
|
| 27 |
+
@ultroid_bot.on(
|
| 28 |
+
NewMsg(
|
| 29 |
+
chats=list(get_flood().keys()),
|
| 30 |
+
),
|
| 31 |
+
)
|
| 32 |
+
async def flood_checm(event):
|
| 33 |
+
count = 1
|
| 34 |
+
chat = (await event.get_chat()).title
|
| 35 |
+
if event.chat_id in _check_flood.keys():
|
| 36 |
+
if event.sender_id == list(_check_flood[event.chat_id].keys())[0]:
|
| 37 |
+
count = _check_flood[event.chat_id][event.sender_id]
|
| 38 |
+
_check_flood[event.chat_id] = {event.sender_id: count + 1}
|
| 39 |
+
else:
|
| 40 |
+
_check_flood[event.chat_id] = {event.sender_id: count}
|
| 41 |
+
else:
|
| 42 |
+
_check_flood[event.chat_id] = {event.sender_id: count}
|
| 43 |
+
if await admin_check(event, silent=True) or getattr(event.sender, "bot", None):
|
| 44 |
+
return
|
| 45 |
+
if event.sender_id in DEVLIST:
|
| 46 |
+
return
|
| 47 |
+
if _check_flood[event.chat_id][event.sender_id] >= int(
|
| 48 |
+
get_flood_limit(event.chat_id)
|
| 49 |
+
):
|
| 50 |
+
try:
|
| 51 |
+
name = event.sender.first_name
|
| 52 |
+
await event.client.edit_permissions(
|
| 53 |
+
event.chat_id, event.sender_id, send_messages=False
|
| 54 |
+
)
|
| 55 |
+
del _check_flood[event.chat_id]
|
| 56 |
+
await event.reply(f"#AntiFlood\n\n{get_string('antiflood_3')}")
|
| 57 |
+
await asst.send_message(
|
| 58 |
+
int(Redis("LOG_CHANNEL")),
|
| 59 |
+
f"#Antiflood\n\n`Muted `[{name}](tg://user?id={event.sender_id})` in {chat}`",
|
| 60 |
+
buttons=Button.inline(
|
| 61 |
+
"Unmute", data=f"anti_{event.sender_id}_{event.chat_id}"
|
| 62 |
+
),
|
| 63 |
+
)
|
| 64 |
+
except BaseException:
|
| 65 |
+
pass
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
@callback(
|
| 69 |
+
re.compile(
|
| 70 |
+
"anti_(.*)",
|
| 71 |
+
),
|
| 72 |
+
)
|
| 73 |
+
async def unmuting(e):
|
| 74 |
+
ino = (e.data_match.group(1)).decode("UTF-8").split("_")
|
| 75 |
+
user = int(ino[0])
|
| 76 |
+
chat = int(ino[1])
|
| 77 |
+
user_name = (await ultroid_bot.get_entity(user)).first_name
|
| 78 |
+
chat_title = (await ultroid_bot.get_entity(chat)).title
|
| 79 |
+
await ultroid_bot.edit_permissions(chat, user, send_messages=True)
|
| 80 |
+
await e.edit(
|
| 81 |
+
f"#Antiflood\n\n`Unmuted `[{user_name}](tg://user?id={user})` in {chat_title}`"
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
@ultroid_cmd(
|
| 86 |
+
pattern="setflood ?(\\d+)",
|
| 87 |
+
admins_only=True,
|
| 88 |
+
)
|
| 89 |
+
async def setflood(e):
|
| 90 |
+
input_ = e.pattern_match.group(1).strip()
|
| 91 |
+
if not input_:
|
| 92 |
+
return await e.eor("`What?`", time=5)
|
| 93 |
+
if not input_.isdigit():
|
| 94 |
+
return await e.eor(get_string("com_3"), time=5)
|
| 95 |
+
if m := set_flood(e.chat_id, input_):
|
| 96 |
+
return await eod(e, get_string("antiflood_4").format(input_))
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@ultroid_cmd(
|
| 100 |
+
pattern="remflood$",
|
| 101 |
+
admins_only=True,
|
| 102 |
+
)
|
| 103 |
+
async def remove_flood(e):
|
| 104 |
+
hmm = rem_flood(e.chat_id)
|
| 105 |
+
try:
|
| 106 |
+
del _check_flood[e.chat_id]
|
| 107 |
+
except BaseException:
|
| 108 |
+
pass
|
| 109 |
+
if hmm:
|
| 110 |
+
return await e.eor(get_string("antiflood_1"), time=5)
|
| 111 |
+
await e.eor(get_string("antiflood_2"), time=5)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
@ultroid_cmd(
|
| 115 |
+
pattern="getflood$",
|
| 116 |
+
admins_only=True,
|
| 117 |
+
)
|
| 118 |
+
async def getflood(e):
|
| 119 |
+
if ok := get_flood_limit(e.chat_id):
|
| 120 |
+
return await e.eor(get_string("antiflood_5").format(ok), time=5)
|
| 121 |
+
await e.eor(get_string("antiflood_2"), time=5)
|
plugins/asstcmd.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_asstcmd")
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
from pyUltroid.dB.asstcmd_db import add_cmd, cmd_reply, list_cmds, rem_cmd
|
| 15 |
+
from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button
|
| 16 |
+
from telethon import events, utils
|
| 17 |
+
|
| 18 |
+
from . import asst, get_string, mediainfo, udB, ultroid_cmd, upload_file
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
@ultroid_cmd(pattern="addcmd( (.*)|$)")
|
| 22 |
+
async def ac(e):
|
| 23 |
+
wrd = (e.pattern_match.group(1).strip()).lower()
|
| 24 |
+
wt = await e.get_reply_message()
|
| 25 |
+
if not (wt and wrd):
|
| 26 |
+
return await e.eor(get_string("asstcmd_1"), time=5)
|
| 27 |
+
if "/" in wrd:
|
| 28 |
+
wrd = wrd.replace("/", "")
|
| 29 |
+
btn = format_btn(wt.buttons) if wt.buttons else None
|
| 30 |
+
if wt and wt.media:
|
| 31 |
+
wut = mediainfo(wt.media)
|
| 32 |
+
if wut.startswith(("pic", "gif")):
|
| 33 |
+
dl = await e.client.download_media(wt.media)
|
| 34 |
+
m = upload_file(dl)
|
| 35 |
+
os.remove(dl)
|
| 36 |
+
elif wut == "video":
|
| 37 |
+
if wt.media.document.size > 8 * 1000 * 1000:
|
| 38 |
+
return await e.eor(get_string("com_4"), time=5)
|
| 39 |
+
dl = await e.client.download_media(wt.media)
|
| 40 |
+
m = upload_file(dl)
|
| 41 |
+
os.remove(dl)
|
| 42 |
+
else:
|
| 43 |
+
m = utils.pack_bot_file_id(wt.media)
|
| 44 |
+
if wt.text:
|
| 45 |
+
txt = wt.text
|
| 46 |
+
if not btn:
|
| 47 |
+
txt, btn = get_msg_button(wt.text)
|
| 48 |
+
add_cmd(wrd, txt, m, btn)
|
| 49 |
+
else:
|
| 50 |
+
add_cmd(wrd, None, m, btn)
|
| 51 |
+
else:
|
| 52 |
+
txt = wt.text
|
| 53 |
+
if not btn:
|
| 54 |
+
txt, btn = get_msg_button(wt.text)
|
| 55 |
+
add_cmd(wrd, txt, None, btn)
|
| 56 |
+
asst.add_handler(
|
| 57 |
+
astcmds,
|
| 58 |
+
events.NewMessage(
|
| 59 |
+
func=lambda x: x.text.startswith("/") and x.text[1:] in list(list_cmds())
|
| 60 |
+
),
|
| 61 |
+
)
|
| 62 |
+
await e.eor(get_string("asstcmd_4").format(wrd))
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
@ultroid_cmd(pattern="remcmd( (.*)|$)")
|
| 66 |
+
async def rc(e):
|
| 67 |
+
wrd = (e.pattern_match.group(1).strip()).lower()
|
| 68 |
+
if not wrd:
|
| 69 |
+
return await e.eor(get_string("asstcmd_2"), time=5)
|
| 70 |
+
wrd = wrd.replace("/", "")
|
| 71 |
+
rem_cmd(wrd)
|
| 72 |
+
await e.eor(get_string("asstcmd_3").format(wrd))
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
@ultroid_cmd(pattern="listcmd$")
|
| 76 |
+
async def lscmd(e):
|
| 77 |
+
if list_cmds():
|
| 78 |
+
ok = get_string("asstcmd_6")
|
| 79 |
+
for x in list_cmds():
|
| 80 |
+
ok += f"/{x}" + "\n"
|
| 81 |
+
return await e.eor(ok)
|
| 82 |
+
return await e.eor(get_string("asstcmd_5"))
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
async def astcmds(e):
|
| 86 |
+
xx = (e.text.replace("/", "")).lower().split()[0]
|
| 87 |
+
if cmd_reply(xx):
|
| 88 |
+
msg, media, bt = cmd_reply(xx)
|
| 89 |
+
if bt:
|
| 90 |
+
bt = create_tl_btn(bt)
|
| 91 |
+
await e.reply(msg, file=media, buttons=bt)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
if udB.get_key("ASST_CMDS"):
|
| 95 |
+
asst.add_handler(
|
| 96 |
+
astcmds,
|
| 97 |
+
events.NewMessage(
|
| 98 |
+
func=lambda x: x.text.startswith("/") and x.text[1:] in list(list_cmds())
|
| 99 |
+
),
|
| 100 |
+
)
|
plugins/audiotools.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
import os
|
| 10 |
+
import time
|
| 11 |
+
from datetime import datetime as dt
|
| 12 |
+
|
| 13 |
+
from pyUltroid.fns.tools import set_attributes
|
| 14 |
+
|
| 15 |
+
from . import (
|
| 16 |
+
LOGS,
|
| 17 |
+
ULTConfig,
|
| 18 |
+
bash,
|
| 19 |
+
downloader,
|
| 20 |
+
eod,
|
| 21 |
+
eor,
|
| 22 |
+
genss,
|
| 23 |
+
get_help,
|
| 24 |
+
get_string,
|
| 25 |
+
humanbytes,
|
| 26 |
+
mediainfo,
|
| 27 |
+
stdr,
|
| 28 |
+
time_formatter,
|
| 29 |
+
ultroid_cmd
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
__doc__ = get_help("help_audiotools")
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
@ultroid_cmd(pattern="makevoice$")
|
| 36 |
+
async def vnc(e):
|
| 37 |
+
if not e.reply_to:
|
| 38 |
+
return await eod(e, get_string("audiotools_1"))
|
| 39 |
+
r = await e.get_reply_message()
|
| 40 |
+
if not mediainfo(r.media).startswith(("audio", "video")):
|
| 41 |
+
return await eod(e, get_string("spcltool_1"))
|
| 42 |
+
xxx = await e.eor(get_string("com_1"))
|
| 43 |
+
file, _ = await e.client.fast_downloader(
|
| 44 |
+
r.document,
|
| 45 |
+
)
|
| 46 |
+
await xxx.edit(get_string("audiotools_2"))
|
| 47 |
+
await bash(
|
| 48 |
+
f"ffmpeg -i '{file.name}' -map 0:a -codec:a libopus -b:a 100k -vbr on out.opus"
|
| 49 |
+
)
|
| 50 |
+
try:
|
| 51 |
+
await e.client.send_message(
|
| 52 |
+
e.chat_id, file="out.opus", force_document=False, reply_to=r
|
| 53 |
+
)
|
| 54 |
+
except Exception as er:
|
| 55 |
+
LOGS.exception(er)
|
| 56 |
+
return await xxx.edit("`Failed to convert in Voice...`")
|
| 57 |
+
await xxx.delete()
|
| 58 |
+
os.remove(file.name)
|
| 59 |
+
os.remove("out.opus")
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
@ultroid_cmd(pattern="atrim( (.*)|$)")
|
| 63 |
+
async def trim_aud(e):
|
| 64 |
+
sec = e.pattern_match.group(1).strip()
|
| 65 |
+
if not sec or "-" not in sec:
|
| 66 |
+
return await eod(e, get_string("audiotools_3"))
|
| 67 |
+
a, b = sec.split("-")
|
| 68 |
+
if int(a) >= int(b):
|
| 69 |
+
return await eod(e, get_string("audiotools_4"))
|
| 70 |
+
vido = await e.get_reply_message()
|
| 71 |
+
if vido and vido.media and mediainfo(vido.media).startswith(("video", "audio")):
|
| 72 |
+
if hasattr(vido.media, "document"):
|
| 73 |
+
vfile = vido.media.document
|
| 74 |
+
name = vido.file.name
|
| 75 |
+
else:
|
| 76 |
+
vfile = vido.media
|
| 77 |
+
name = ""
|
| 78 |
+
if not name:
|
| 79 |
+
name = dt.now().isoformat("_", "seconds") + ".mp4"
|
| 80 |
+
xxx = await e.eor(get_string("audiotools_5"))
|
| 81 |
+
c_time = time.time()
|
| 82 |
+
file = await downloader(
|
| 83 |
+
f"resources/downloads/{name}",
|
| 84 |
+
vfile,
|
| 85 |
+
xxx,
|
| 86 |
+
c_time,
|
| 87 |
+
f"Downloading {name}...",
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
o_size = os.path.getsize(file.name)
|
| 91 |
+
d_time = time.time()
|
| 92 |
+
diff = time_formatter((d_time - c_time) * 1000)
|
| 93 |
+
file_name = (file.name).split("/")[-1]
|
| 94 |
+
out = file_name.replace(file_name.split(".")[-1], "_trimmed.aac")
|
| 95 |
+
if int(b) > int(await genss(file.name)):
|
| 96 |
+
os.remove(file.name)
|
| 97 |
+
return await eod(xxx, get_string("audiotools_6"))
|
| 98 |
+
ss, dd = stdr(int(a)), stdr(int(b))
|
| 99 |
+
xxx = await xxx.edit(
|
| 100 |
+
f"Downloaded `{file.name}` of `{humanbytes(o_size)}` in `{diff}`.\n\nNow Trimming Audio from `{ss}` to `{dd}`..."
|
| 101 |
+
)
|
| 102 |
+
cmd = f'ffmpeg -i "{file.name}" -preset ultrafast -ss {ss} -to {dd} -vn -acodec copy "{out}" -y'
|
| 103 |
+
await bash(cmd)
|
| 104 |
+
os.remove(file.name)
|
| 105 |
+
f_time = time.time()
|
| 106 |
+
n_file, _ = await e.client.fast_uploader(
|
| 107 |
+
out, show_progress=True, event=e, message="Uploading...", to_delete=True
|
| 108 |
+
)
|
| 109 |
+
attributes = await set_attributes(out)
|
| 110 |
+
|
| 111 |
+
caption = get_string("audiotools_7").format(ss, dd)
|
| 112 |
+
await e.client.send_file(
|
| 113 |
+
e.chat_id,
|
| 114 |
+
n_file,
|
| 115 |
+
thumb=ULTConfig.thumb,
|
| 116 |
+
caption=caption,
|
| 117 |
+
attributes=attributes,
|
| 118 |
+
force_document=False,
|
| 119 |
+
reply_to=e.reply_to_msg_id,
|
| 120 |
+
)
|
| 121 |
+
await xxx.delete()
|
| 122 |
+
else:
|
| 123 |
+
await e.eor(get_string("audiotools_1"), time=5)
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
@ultroid_cmd(pattern="extractaudio$")
|
| 127 |
+
async def ex_aud(e):
|
| 128 |
+
reply = await e.get_reply_message()
|
| 129 |
+
if not (reply and reply.media and mediainfo(reply.media).startswith("video")):
|
| 130 |
+
return await e.eor(get_string("audiotools_8"))
|
| 131 |
+
name = reply.file.name or "video.mp4"
|
| 132 |
+
vfile = reply.media.document
|
| 133 |
+
msg = await e.eor(get_string("com_1"))
|
| 134 |
+
c_time = time.time()
|
| 135 |
+
file = await downloader(
|
| 136 |
+
f"resources/downloads/{name}",
|
| 137 |
+
vfile,
|
| 138 |
+
msg,
|
| 139 |
+
c_time,
|
| 140 |
+
f"Downloading {name}...",
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
out_file = f"{file.name}.aac"
|
| 144 |
+
cmd = f"ffmpeg -i {file.name} -vn -acodec copy {out_file}"
|
| 145 |
+
o, err = await bash(cmd)
|
| 146 |
+
os.remove(file.name)
|
| 147 |
+
attributes = await set_attributes(out_file)
|
| 148 |
+
|
| 149 |
+
f_time = time.time()
|
| 150 |
+
try:
|
| 151 |
+
n_file, _ = await e.client.fast_uploader(
|
| 152 |
+
out_file, show_progress=True, event=e, message="Uploading...", to_delete=True
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
except FileNotFoundError:
|
| 156 |
+
return await eor(msg, get_string("audiotools_9"))
|
| 157 |
+
await e.reply(
|
| 158 |
+
get_string("audiotools_10"),
|
| 159 |
+
file=n_file,
|
| 160 |
+
thumb=ULTConfig.thumb,
|
| 161 |
+
attributes=attributes,
|
| 162 |
+
)
|
| 163 |
+
await msg.delete()
|
plugins/autoban.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_autoban")
|
| 11 |
+
|
| 12 |
+
from telethon import events
|
| 13 |
+
|
| 14 |
+
from pyUltroid.dB.base import KeyManager
|
| 15 |
+
|
| 16 |
+
from . import LOGS, asst, ultroid_bot, ultroid_cmd
|
| 17 |
+
|
| 18 |
+
Keym = KeyManager("DND_CHATS", cast=list)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def join_func(e):
|
| 22 |
+
return e.user_joined and Keym.contains(e.chat_id)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
async def dnd_func(event):
|
| 26 |
+
for user in event.users:
|
| 27 |
+
try:
|
| 28 |
+
await (await event.client.kick_participant(event.chat_id, user)).delete()
|
| 29 |
+
except Exception as ex:
|
| 30 |
+
LOGS.error("Error in DND:")
|
| 31 |
+
LOGS.exception(ex)
|
| 32 |
+
await event.delete()
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
@ultroid_cmd(
|
| 36 |
+
pattern="autokick (on|off)$",
|
| 37 |
+
admins_only=True,
|
| 38 |
+
manager=True,
|
| 39 |
+
require="ban_users",
|
| 40 |
+
fullsudo=True,
|
| 41 |
+
)
|
| 42 |
+
async def _(event):
|
| 43 |
+
match = event.pattern_match.group(1)
|
| 44 |
+
if match == "on":
|
| 45 |
+
if Keym.contains(event.chat_id):
|
| 46 |
+
return await event.eor("`Chat already in do not disturb mode.`", time=3)
|
| 47 |
+
Keym.add(event.chat_id)
|
| 48 |
+
event.client.add_handler(dnd_func, events.ChatAction(func=join_func))
|
| 49 |
+
await event.eor("`Do not disturb mode activated for this chat.`", time=3)
|
| 50 |
+
elif match == "off":
|
| 51 |
+
if not Keym.contains(event.chat_id):
|
| 52 |
+
return await event.eor("`Chat is not in do not disturb mode.`", time=3)
|
| 53 |
+
Keym.remove(event.chat_id)
|
| 54 |
+
await event.eor("`Do not disturb mode deactivated for this chat.`", time=3)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
if Keym.get():
|
| 58 |
+
ultroid_bot.add_handler(dnd_func, events.ChatAction(func=join_func))
|
| 59 |
+
asst.add_handler(dnd_func, events.ChatAction(func=join_func))
|
plugins/autopic.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
import asyncio
|
| 10 |
+
import os
|
| 11 |
+
import random
|
| 12 |
+
from random import shuffle
|
| 13 |
+
import aiohttp
|
| 14 |
+
import re
|
| 15 |
+
from telethon.tl.functions.photos import UploadProfilePhotoRequest
|
| 16 |
+
from PIL import Image
|
| 17 |
+
|
| 18 |
+
from pyUltroid.fns.helper import download_file, fast_download
|
| 19 |
+
|
| 20 |
+
from . import LOGS, get_help, get_string, udB, ultroid_bot, ultroid_cmd
|
| 21 |
+
|
| 22 |
+
__doc__ = get_help("help_autopic")
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
async def get_google_images(query: str):
|
| 26 |
+
"""Extract image URLs from Google Images search results with fallbacks"""
|
| 27 |
+
|
| 28 |
+
headers = {
|
| 29 |
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
search_url = f"https://www.google.com/search?q={query}&tbm=isch"
|
| 33 |
+
|
| 34 |
+
# Domains to exclude
|
| 35 |
+
excluded_domains = [
|
| 36 |
+
'gstatic.com',
|
| 37 |
+
'google.com',
|
| 38 |
+
'googleusercontent.com',
|
| 39 |
+
'ssl.google.com'
|
| 40 |
+
]
|
| 41 |
+
|
| 42 |
+
def is_valid_url(url):
|
| 43 |
+
return not any(domain in url.lower() for domain in excluded_domains)
|
| 44 |
+
|
| 45 |
+
try:
|
| 46 |
+
async with aiohttp.ClientSession() as session:
|
| 47 |
+
async with session.get(search_url, headers=headers) as response:
|
| 48 |
+
html = await response.text()
|
| 49 |
+
|
| 50 |
+
# Try to extract from search results div first
|
| 51 |
+
img_urls = []
|
| 52 |
+
search_pattern = r'<div id="search".*?>(.*?)</div>'
|
| 53 |
+
search_match = re.search(search_pattern, html, re.DOTALL)
|
| 54 |
+
if search_match:
|
| 55 |
+
search_content = search_match.group(1)
|
| 56 |
+
url_pattern = r'https://[^\"]*?\.(?:jpg|jpeg|png|webp)'
|
| 57 |
+
url_matches = re.finditer(url_pattern, search_content, re.IGNORECASE)
|
| 58 |
+
for url_match in url_matches:
|
| 59 |
+
url = url_match.group(0)
|
| 60 |
+
if url not in img_urls and is_valid_url(url):
|
| 61 |
+
img_urls.append(url)
|
| 62 |
+
|
| 63 |
+
# Fallback to tdeeNb div if no results
|
| 64 |
+
if not img_urls:
|
| 65 |
+
pattern = r'<div jsname="tdeeNb"[^>]*>(.*?)</div>'
|
| 66 |
+
matches = re.finditer(pattern, html, re.DOTALL)
|
| 67 |
+
for match in matches:
|
| 68 |
+
div_content = match.group(1)
|
| 69 |
+
url_pattern = r'https://[^\"]*?\.(?:jpg|jpeg|png|webp)'
|
| 70 |
+
url_matches = re.finditer(url_pattern, div_content, re.IGNORECASE)
|
| 71 |
+
for url_match in url_matches:
|
| 72 |
+
url = url_match.group(0)
|
| 73 |
+
if url not in img_urls and is_valid_url(url):
|
| 74 |
+
img_urls.append(url)
|
| 75 |
+
|
| 76 |
+
# Fallback to general image search if still no results
|
| 77 |
+
if not img_urls:
|
| 78 |
+
pattern = r"https://[^\"]*?\.(?:jpg|jpeg|png|webp)"
|
| 79 |
+
matches = re.finditer(pattern, html, re.IGNORECASE)
|
| 80 |
+
for match in matches:
|
| 81 |
+
url = match.group(0)
|
| 82 |
+
if url not in img_urls and is_valid_url(url):
|
| 83 |
+
img_urls.append(url)
|
| 84 |
+
|
| 85 |
+
# Final fallback to data URLs if still no results
|
| 86 |
+
if not img_urls:
|
| 87 |
+
pattern = r'data:image/(?:jpeg|png|webp);base64,[^\"]*'
|
| 88 |
+
matches = re.finditer(pattern, html, re.IGNORECASE)
|
| 89 |
+
for match in matches:
|
| 90 |
+
url = match.group(0)
|
| 91 |
+
if url not in img_urls:
|
| 92 |
+
img_urls.append(url)
|
| 93 |
+
|
| 94 |
+
return img_urls
|
| 95 |
+
|
| 96 |
+
except Exception as e:
|
| 97 |
+
print(f"Error fetching Google images: {e}")
|
| 98 |
+
return []
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
@ultroid_cmd(pattern="autopic( (.*)|$)")
|
| 102 |
+
async def autopic(e):
|
| 103 |
+
search = e.pattern_match.group(1).strip()
|
| 104 |
+
if udB.get_key("AUTOPIC") and not search:
|
| 105 |
+
udB.del_key("AUTOPIC")
|
| 106 |
+
return await e.eor(get_string("autopic_5"))
|
| 107 |
+
if not search:
|
| 108 |
+
return await e.eor(get_string("autopic_1"), time=5)
|
| 109 |
+
e = await e.eor(get_string("com_1"))
|
| 110 |
+
images = await get_google_images(search)
|
| 111 |
+
if not images:
|
| 112 |
+
return await e.eor(get_string("autopic_2").format(search), time=5)
|
| 113 |
+
await e.eor(get_string("autopic_3").format(search))
|
| 114 |
+
udB.set_key("AUTOPIC", search)
|
| 115 |
+
SLEEP_TIME = udB.get_key("SLEEP_TIME") or 1221
|
| 116 |
+
while True:
|
| 117 |
+
for lie in images:
|
| 118 |
+
if udB.get_key("AUTOPIC") != search:
|
| 119 |
+
return
|
| 120 |
+
download_path, stime = await fast_download(lie, "resources/downloads/autopic.jpg")
|
| 121 |
+
img = Image.open(download_path)
|
| 122 |
+
img.save("resources/downloads/autopic.jpg")
|
| 123 |
+
file = await e.client.upload_file("resources/downloads/autopic.jpg")
|
| 124 |
+
await e.client(UploadProfilePhotoRequest(file=file))
|
| 125 |
+
os.remove("resources/downloads/autopic.jpg")
|
| 126 |
+
await asyncio.sleep(SLEEP_TIME)
|
| 127 |
+
|
| 128 |
+
shuffle(images)
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
if search := udB.get_key("AUTOPIC"):
|
| 132 |
+
images = {}
|
| 133 |
+
sleep = udB.get_key("SLEEP_TIME") or 1221
|
| 134 |
+
|
| 135 |
+
async def autopic_func():
|
| 136 |
+
search = udB.get_key("AUTOPIC")
|
| 137 |
+
if images.get(search) is None:
|
| 138 |
+
images[search] = await get_google_images(search)
|
| 139 |
+
if not images.get(search):
|
| 140 |
+
return
|
| 141 |
+
img = random.choice(images[search])
|
| 142 |
+
filee, stime = await fast_download(img, "resources/downloads/autopic.jpg")
|
| 143 |
+
img = Image.open(filee)
|
| 144 |
+
img.save("resources/downloads/autopic.jpg")
|
| 145 |
+
file = await ultroid_bot.upload_file("resources/downloads/autopic.jpg")
|
| 146 |
+
await ultroid_bot(UploadProfilePhotoRequest(file=file))
|
| 147 |
+
os.remove(filee)
|
| 148 |
+
|
| 149 |
+
try:
|
| 150 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
| 151 |
+
|
| 152 |
+
schedule = AsyncIOScheduler()
|
| 153 |
+
schedule.add_job(autopic_func, "interval", seconds=sleep)
|
| 154 |
+
schedule.start()
|
| 155 |
+
except ModuleNotFoundError as er:
|
| 156 |
+
LOGS.error(f"autopic: '{er.name}' not installed.")
|
plugins/beautify.py
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_beautify")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
import os
|
| 14 |
+
import random
|
| 15 |
+
|
| 16 |
+
from telethon.utils import get_display_name
|
| 17 |
+
from urllib.parse import urlencode
|
| 18 |
+
from . import Carbon, ultroid_cmd, get_string, inline_mention
|
| 19 |
+
from secrets import token_hex
|
| 20 |
+
|
| 21 |
+
_colorspath = "resources/colorlist.txt"
|
| 22 |
+
|
| 23 |
+
if os.path.exists(_colorspath):
|
| 24 |
+
with open(_colorspath, "r") as f:
|
| 25 |
+
all_col = f.read().split()
|
| 26 |
+
else:
|
| 27 |
+
all_col = []
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
@ultroid_cmd(
|
| 31 |
+
pattern="(rc|c)arbon",
|
| 32 |
+
)
|
| 33 |
+
async def cr_bn(event):
|
| 34 |
+
xxxx = await event.eor(get_string("com_1"))
|
| 35 |
+
te = event.pattern_match.group(1)
|
| 36 |
+
col = random.choice(all_col) if te[0] == "r" else "White"
|
| 37 |
+
if event.reply_to_msg_id:
|
| 38 |
+
temp = await event.get_reply_message()
|
| 39 |
+
if temp.media:
|
| 40 |
+
b = await event.client.download_media(temp)
|
| 41 |
+
with open(b) as a:
|
| 42 |
+
code = a.read()
|
| 43 |
+
os.remove(b)
|
| 44 |
+
else:
|
| 45 |
+
code = temp.message
|
| 46 |
+
else:
|
| 47 |
+
try:
|
| 48 |
+
code = event.text.split(" ", maxsplit=1)[1]
|
| 49 |
+
except IndexError:
|
| 50 |
+
return await xxxx.eor(get_string("carbon_2"))
|
| 51 |
+
xx = await Carbon(code=code, file_name="ultroid_carbon", backgroundColor=col)
|
| 52 |
+
if isinstance(xx, dict):
|
| 53 |
+
await xxxx.edit(f"`{xx}`")
|
| 54 |
+
return
|
| 55 |
+
await xxxx.delete()
|
| 56 |
+
await event.reply(
|
| 57 |
+
f"Carbonised by {inline_mention(event.sender)}",
|
| 58 |
+
file=xx,
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
@ultroid_cmd(
|
| 63 |
+
pattern="ccarbon( (.*)|$)",
|
| 64 |
+
)
|
| 65 |
+
async def crbn(event):
|
| 66 |
+
match = event.pattern_match.group(1).strip()
|
| 67 |
+
if not match:
|
| 68 |
+
return await event.eor(get_string("carbon_3"))
|
| 69 |
+
msg = await event.eor(get_string("com_1"))
|
| 70 |
+
if event.reply_to_msg_id:
|
| 71 |
+
temp = await event.get_reply_message()
|
| 72 |
+
if temp.media:
|
| 73 |
+
b = await event.client.download_media(temp)
|
| 74 |
+
with open(b) as a:
|
| 75 |
+
code = a.read()
|
| 76 |
+
os.remove(b)
|
| 77 |
+
else:
|
| 78 |
+
code = temp.message
|
| 79 |
+
else:
|
| 80 |
+
try:
|
| 81 |
+
match = match.split(" ", maxsplit=1)
|
| 82 |
+
code = match[1]
|
| 83 |
+
match = match[0]
|
| 84 |
+
except IndexError:
|
| 85 |
+
return await msg.eor(get_string("carbon_2"))
|
| 86 |
+
xx = await Carbon(code=code, backgroundColor=match)
|
| 87 |
+
await msg.delete()
|
| 88 |
+
await event.reply(
|
| 89 |
+
f"Carbonised by {inline_mention(event.sender)}",
|
| 90 |
+
file=xx,
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
RaySoTheme = [
|
| 95 |
+
"meadow",
|
| 96 |
+
"breeze",
|
| 97 |
+
"raindrop",
|
| 98 |
+
"candy",
|
| 99 |
+
"crimson",
|
| 100 |
+
"falcon",
|
| 101 |
+
"sunset",
|
| 102 |
+
"noir",
|
| 103 |
+
"midnight",
|
| 104 |
+
"bitmap",
|
| 105 |
+
"ice",
|
| 106 |
+
"sand",
|
| 107 |
+
"forest",
|
| 108 |
+
"mono",
|
| 109 |
+
]
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
@ultroid_cmd(pattern="rayso")
|
| 113 |
+
async def pass_on(ult):
|
| 114 |
+
try:
|
| 115 |
+
from playwright.async_api import async_playwright
|
| 116 |
+
except ImportError:
|
| 117 |
+
await ult.eor(
|
| 118 |
+
"`playwright` is not installed!\nPlease install it to use this command.."
|
| 119 |
+
)
|
| 120 |
+
return
|
| 121 |
+
|
| 122 |
+
proc = await ult.eor(get_string("com_1"))
|
| 123 |
+
spli = ult.text.split()
|
| 124 |
+
theme, dark, title, text = None, True, get_display_name(ult.chat), None
|
| 125 |
+
if len(spli) > 1:
|
| 126 |
+
if spli[1] in RaySoTheme:
|
| 127 |
+
theme = spli[1]
|
| 128 |
+
if len(spli) > 2:
|
| 129 |
+
text = " ".join(spli[2:])
|
| 130 |
+
else:
|
| 131 |
+
text = " ".join(spli[1:])
|
| 132 |
+
if ult.is_reply:
|
| 133 |
+
try:
|
| 134 |
+
msg = await ult.get_reply_message()
|
| 135 |
+
text = msg.message if not text else text
|
| 136 |
+
title = get_display_name(msg.sender)
|
| 137 |
+
if not theme and spli[1] in RaySoTheme:
|
| 138 |
+
theme = spli[1]
|
| 139 |
+
except Exception as sam:
|
| 140 |
+
LOGS.exception(sam)
|
| 141 |
+
if not text:
|
| 142 |
+
await proc.eor("No text to beautify!")
|
| 143 |
+
return
|
| 144 |
+
if not theme:
|
| 145 |
+
theme = random.choice(RaySoTheme)
|
| 146 |
+
cleaned_text = "\n".join([line.strip() for line in text.splitlines()])
|
| 147 |
+
name = token_hex(8) + ".png"
|
| 148 |
+
data = {"darkMode": dark, "theme": theme, "title": title}
|
| 149 |
+
url = f"https://ray.so/#{urlencode(data)}"
|
| 150 |
+
async with async_playwright() as play:
|
| 151 |
+
try:
|
| 152 |
+
browser = await play.chromium.launch()
|
| 153 |
+
page = await browser.new_page()
|
| 154 |
+
await page.goto(url)
|
| 155 |
+
await page.wait_for_load_state("networkidle")
|
| 156 |
+
try:
|
| 157 |
+
await page.wait_for_selector(
|
| 158 |
+
"div[class*='Editor_editor__']", timeout=60000
|
| 159 |
+
)
|
| 160 |
+
editor = await page.query_selector("div[class*='Editor_editor__']")
|
| 161 |
+
await editor.focus()
|
| 162 |
+
await editor.click()
|
| 163 |
+
|
| 164 |
+
for line in cleaned_text.split("\n"):
|
| 165 |
+
await page.keyboard.type(line)
|
| 166 |
+
await page.keyboard.press("Enter")
|
| 167 |
+
|
| 168 |
+
await page.evaluate(
|
| 169 |
+
"""() => {
|
| 170 |
+
const button = document.querySelector('button[aria-label="Export as PNG"]');
|
| 171 |
+
button.click();
|
| 172 |
+
}"""
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
async with page.expect_download() as download_info:
|
| 176 |
+
download = await download_info.value
|
| 177 |
+
await download.save_as(name)
|
| 178 |
+
except playwright._impl._errors.TimeoutError:
|
| 179 |
+
LOGS.error("Timeout error: Selector not found within 60 seconds.")
|
| 180 |
+
await proc.eor("Failed to find the editor within 60 seconds.")
|
| 181 |
+
return
|
| 182 |
+
except Exception as e:
|
| 183 |
+
LOGS.error(f"Error occurred during playwright operation: {e}")
|
| 184 |
+
await proc.eor("An error occurred during the operation.")
|
| 185 |
+
return
|
| 186 |
+
finally:
|
| 187 |
+
if os.path.exists(name):
|
| 188 |
+
try:
|
| 189 |
+
await ult.reply(file=name)
|
| 190 |
+
await proc.try_delete()
|
| 191 |
+
os.remove(name)
|
| 192 |
+
except Exception as e:
|
| 193 |
+
LOGS.error(f"Error occurred while replying with the file: {e}")
|
| 194 |
+
await proc.eor("Failed to send the file.")
|
| 195 |
+
else:
|
| 196 |
+
LOGS.error(f"Error: File {name} not found or inaccessible.")
|
| 197 |
+
await proc.eor("Failed to save the file.")
|
plugins/bot.py
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_bot")
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
import sys
|
| 14 |
+
import time
|
| 15 |
+
from platform import python_version as pyver
|
| 16 |
+
from random import choice
|
| 17 |
+
|
| 18 |
+
from telethon import __version__
|
| 19 |
+
from telethon.errors.rpcerrorlist import (
|
| 20 |
+
BotMethodInvalidError,
|
| 21 |
+
ChatSendMediaForbiddenError,
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
from pyUltroid.version import __version__ as UltVer
|
| 25 |
+
|
| 26 |
+
from . import HOSTED_ON, LOGS
|
| 27 |
+
|
| 28 |
+
try:
|
| 29 |
+
from git import Repo
|
| 30 |
+
except ImportError:
|
| 31 |
+
LOGS.error("bot: 'gitpython' module not found!")
|
| 32 |
+
Repo = None
|
| 33 |
+
|
| 34 |
+
from telethon.utils import resolve_bot_file_id
|
| 35 |
+
|
| 36 |
+
from . import (
|
| 37 |
+
ATRA_COL,
|
| 38 |
+
LOGS,
|
| 39 |
+
OWNER_NAME,
|
| 40 |
+
ULTROID_IMAGES,
|
| 41 |
+
Button,
|
| 42 |
+
Carbon,
|
| 43 |
+
Telegraph,
|
| 44 |
+
Var,
|
| 45 |
+
allcmds,
|
| 46 |
+
asst,
|
| 47 |
+
bash,
|
| 48 |
+
call_back,
|
| 49 |
+
callback,
|
| 50 |
+
def_logs,
|
| 51 |
+
eor,
|
| 52 |
+
get_string,
|
| 53 |
+
heroku_logs,
|
| 54 |
+
in_pattern,
|
| 55 |
+
inline_pic,
|
| 56 |
+
restart,
|
| 57 |
+
shutdown,
|
| 58 |
+
start_time,
|
| 59 |
+
time_formatter,
|
| 60 |
+
udB,
|
| 61 |
+
ultroid_cmd,
|
| 62 |
+
ultroid_version,
|
| 63 |
+
updater,
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def ULTPIC():
|
| 68 |
+
return inline_pic() or choice(ULTROID_IMAGES)
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
buttons = [
|
| 72 |
+
[
|
| 73 |
+
Button.url(get_string("bot_3"), "https://github.com/TeamUltroid/Ultroid"),
|
| 74 |
+
Button.url(get_string("bot_4"), "t.me/UltroidSupportChat"),
|
| 75 |
+
]
|
| 76 |
+
]
|
| 77 |
+
|
| 78 |
+
# Will move to strings
|
| 79 |
+
alive_txt = """
|
| 80 |
+
The Ultroid Userbot
|
| 81 |
+
|
| 82 |
+
◍ Version - {}
|
| 83 |
+
◍ Py-Ultroid - {}
|
| 84 |
+
◍ Telethon - {}
|
| 85 |
+
"""
|
| 86 |
+
|
| 87 |
+
in_alive = "{}\n\n🌀 <b>Ultroid Version -><b> <code>{}</code>\n🌀 <b>PyUltroid -></b> <code>{}</code>\n🌀 <b>Python -></b> <code>{}</code>\n🌀 <b>Uptime -></b> <code>{}</code>\n🌀 <b>Branch -></b>[ {} ]\n\n• <b>Join @TeamUltroid</b>"
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
@callback("alive")
|
| 91 |
+
async def alive(event):
|
| 92 |
+
text = alive_txt.format(ultroid_version, UltVer, __version__)
|
| 93 |
+
await event.answer(text, alert=True)
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
@ultroid_cmd(
|
| 97 |
+
pattern="alive( (.*)|$)",
|
| 98 |
+
)
|
| 99 |
+
async def lol(ult):
|
| 100 |
+
match = ult.pattern_match.group(1).strip()
|
| 101 |
+
inline = None
|
| 102 |
+
if match in ["inline", "i"]:
|
| 103 |
+
try:
|
| 104 |
+
res = await ult.client.inline_query(asst.me.username, "alive")
|
| 105 |
+
return await res[0].click(ult.chat_id)
|
| 106 |
+
except BotMethodInvalidError:
|
| 107 |
+
pass
|
| 108 |
+
except BaseException as er:
|
| 109 |
+
LOGS.exception(er)
|
| 110 |
+
inline = True
|
| 111 |
+
pic = udB.get_key("ALIVE_PIC")
|
| 112 |
+
if isinstance(pic, list):
|
| 113 |
+
pic = choice(pic)
|
| 114 |
+
uptime = time_formatter((time.time() - start_time) * 1000)
|
| 115 |
+
header = udB.get_key("ALIVE_TEXT") or get_string("bot_1")
|
| 116 |
+
y = Repo().active_branch
|
| 117 |
+
xx = Repo().remotes[0].config_reader.get("url")
|
| 118 |
+
rep = xx.replace(".git", f"/tree/{y}")
|
| 119 |
+
kk = f" `[{y}]({rep})` "
|
| 120 |
+
if inline:
|
| 121 |
+
kk = f"<a href={rep}>{y}</a>"
|
| 122 |
+
parse = "html"
|
| 123 |
+
als = in_alive.format(
|
| 124 |
+
header,
|
| 125 |
+
f"{ultroid_version} [{HOSTED_ON}]",
|
| 126 |
+
UltVer,
|
| 127 |
+
pyver(),
|
| 128 |
+
uptime,
|
| 129 |
+
kk,
|
| 130 |
+
)
|
| 131 |
+
|
| 132 |
+
if _e := udB.get_key("ALIVE_EMOJI"):
|
| 133 |
+
als = als.replace("🌀", _e)
|
| 134 |
+
else:
|
| 135 |
+
parse = "md"
|
| 136 |
+
als = (get_string("alive_1")).format(
|
| 137 |
+
header,
|
| 138 |
+
OWNER_NAME,
|
| 139 |
+
f"{ultroid_version} [{HOSTED_ON}]",
|
| 140 |
+
UltVer,
|
| 141 |
+
uptime,
|
| 142 |
+
pyver(),
|
| 143 |
+
__version__,
|
| 144 |
+
kk,
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
if a := udB.get_key("ALIVE_EMOJI"):
|
| 148 |
+
als = als.replace("✵", a)
|
| 149 |
+
if pic:
|
| 150 |
+
try:
|
| 151 |
+
await ult.reply(
|
| 152 |
+
als,
|
| 153 |
+
file=pic,
|
| 154 |
+
parse_mode=parse,
|
| 155 |
+
link_preview=False,
|
| 156 |
+
buttons=buttons if inline else None,
|
| 157 |
+
)
|
| 158 |
+
return await ult.try_delete()
|
| 159 |
+
except ChatSendMediaForbiddenError:
|
| 160 |
+
pass
|
| 161 |
+
except BaseException as er:
|
| 162 |
+
LOGS.exception(er)
|
| 163 |
+
try:
|
| 164 |
+
await ult.reply(file=pic)
|
| 165 |
+
await ult.reply(
|
| 166 |
+
als,
|
| 167 |
+
parse_mode=parse,
|
| 168 |
+
buttons=buttons if inline else None,
|
| 169 |
+
link_preview=False,
|
| 170 |
+
)
|
| 171 |
+
return await ult.try_delete()
|
| 172 |
+
except BaseException as er:
|
| 173 |
+
LOGS.exception(er)
|
| 174 |
+
await eor(
|
| 175 |
+
ult,
|
| 176 |
+
als,
|
| 177 |
+
parse_mode=parse,
|
| 178 |
+
link_preview=False,
|
| 179 |
+
buttons=buttons if inline else None,
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
@ultroid_cmd(pattern="ping$", chats=[], type=["official", "assistant"])
|
| 184 |
+
async def _(event):
|
| 185 |
+
start = time.time()
|
| 186 |
+
x = await event.eor("Pong !")
|
| 187 |
+
end = round((time.time() - start) * 1000)
|
| 188 |
+
uptime = time_formatter((time.time() - start_time) * 1000)
|
| 189 |
+
await x.edit(get_string("ping").format(end, uptime))
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
@ultroid_cmd(
|
| 193 |
+
pattern="cmds$",
|
| 194 |
+
)
|
| 195 |
+
async def cmds(event):
|
| 196 |
+
await allcmds(event, Telegraph)
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
heroku_api = Var.HEROKU_API
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
@ultroid_cmd(
|
| 203 |
+
pattern="restart$",
|
| 204 |
+
fullsudo=True,
|
| 205 |
+
)
|
| 206 |
+
async def restartbt(ult):
|
| 207 |
+
ok = await ult.eor(get_string("bot_5"))
|
| 208 |
+
call_back()
|
| 209 |
+
who = "bot" if ult.client._bot else "user"
|
| 210 |
+
udB.set_key("_RESTART", f"{who}_{ult.chat_id}_{ok.id}")
|
| 211 |
+
if heroku_api:
|
| 212 |
+
return await restart(ok)
|
| 213 |
+
await bash("git pull && pip3 install -r requirements.txt")
|
| 214 |
+
await bash("pip3 install -r requirements.txt --break-system-packages")
|
| 215 |
+
if len(sys.argv) > 1:
|
| 216 |
+
os.execl(sys.executable, sys.executable, "main.py")
|
| 217 |
+
else:
|
| 218 |
+
os.execl(sys.executable, sys.executable, "-m", "pyUltroid")
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
@ultroid_cmd(
|
| 222 |
+
pattern="shutdown$",
|
| 223 |
+
fullsudo=True,
|
| 224 |
+
)
|
| 225 |
+
async def shutdownbot(ult):
|
| 226 |
+
await shutdown(ult)
|
| 227 |
+
|
| 228 |
+
|
| 229 |
+
@ultroid_cmd(
|
| 230 |
+
pattern="logs( (.*)|$)",
|
| 231 |
+
chats=[],
|
| 232 |
+
)
|
| 233 |
+
async def _(event):
|
| 234 |
+
opt = event.pattern_match.group(1).strip()
|
| 235 |
+
file = f"ultroid{sys.argv[-1]}.log" if len(sys.argv) > 1 else "ultroid.log"
|
| 236 |
+
if opt == "heroku":
|
| 237 |
+
await heroku_logs(event)
|
| 238 |
+
elif opt == "carbon" and Carbon:
|
| 239 |
+
event = await event.eor(get_string("com_1"))
|
| 240 |
+
with open(file, "r") as f:
|
| 241 |
+
code = f.read()[-2500:]
|
| 242 |
+
file = await Carbon(
|
| 243 |
+
file_name="ultroid-logs",
|
| 244 |
+
code=code,
|
| 245 |
+
backgroundColor=choice(ATRA_COL),
|
| 246 |
+
)
|
| 247 |
+
if isinstance(file, dict):
|
| 248 |
+
await event.eor(f"`{file}`")
|
| 249 |
+
return
|
| 250 |
+
await event.reply("**Ultroid Logs.**", file=file)
|
| 251 |
+
elif opt == "open":
|
| 252 |
+
with open("ultroid.log", "r") as f:
|
| 253 |
+
file = f.read()[-4000:]
|
| 254 |
+
return await event.eor(f"`{file}`")
|
| 255 |
+
elif (
|
| 256 |
+
opt.isdigit() and 5 <= int(opt) <= 100
|
| 257 |
+
): # Check if input is a number between 10 and 100
|
| 258 |
+
num_lines = int(opt)
|
| 259 |
+
with open("ultroid.log", "r") as f:
|
| 260 |
+
lines = f.readlines()[-num_lines:]
|
| 261 |
+
file = "".join(lines)
|
| 262 |
+
return await event.eor(f"`{file}`")
|
| 263 |
+
else:
|
| 264 |
+
await def_logs(event, file)
|
| 265 |
+
await event.try_delete()
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
@in_pattern("alive", owner=True)
|
| 269 |
+
async def inline_alive(ult):
|
| 270 |
+
pic = udB.get_key("ALIVE_PIC")
|
| 271 |
+
if isinstance(pic, list):
|
| 272 |
+
pic = choice(pic)
|
| 273 |
+
uptime = time_formatter((time.time() - start_time) * 1000)
|
| 274 |
+
header = udB.get_key("ALIVE_TEXT") or get_string("bot_1")
|
| 275 |
+
y = Repo().active_branch
|
| 276 |
+
xx = Repo().remotes[0].config_reader.get("url")
|
| 277 |
+
rep = xx.replace(".git", f"/tree/{y}")
|
| 278 |
+
kk = f"<a href={rep}>{y}</a>"
|
| 279 |
+
als = in_alive.format(
|
| 280 |
+
header, f"{ultroid_version} [{HOSTED_ON}]", UltVer, pyver(), uptime, kk
|
| 281 |
+
)
|
| 282 |
+
|
| 283 |
+
if _e := udB.get_key("ALIVE_EMOJI"):
|
| 284 |
+
als = als.replace("🌀", _e)
|
| 285 |
+
builder = ult.builder
|
| 286 |
+
if pic:
|
| 287 |
+
try:
|
| 288 |
+
if ".jpg" in pic:
|
| 289 |
+
results = [
|
| 290 |
+
await builder.photo(
|
| 291 |
+
pic, text=als, parse_mode="html", buttons=buttons
|
| 292 |
+
)
|
| 293 |
+
]
|
| 294 |
+
else:
|
| 295 |
+
if _pic := resolve_bot_file_id(pic):
|
| 296 |
+
pic = _pic
|
| 297 |
+
buttons.insert(
|
| 298 |
+
0, [Button.inline(get_string("bot_2"), data="alive")]
|
| 299 |
+
)
|
| 300 |
+
results = [
|
| 301 |
+
await builder.document(
|
| 302 |
+
pic,
|
| 303 |
+
title="Inline Alive",
|
| 304 |
+
description="@TeamUltroid",
|
| 305 |
+
parse_mode="html",
|
| 306 |
+
buttons=buttons,
|
| 307 |
+
)
|
| 308 |
+
]
|
| 309 |
+
return await ult.answer(results)
|
| 310 |
+
except BaseException as er:
|
| 311 |
+
LOGS.exception(er)
|
| 312 |
+
result = [
|
| 313 |
+
await builder.article(
|
| 314 |
+
"Alive", text=als, parse_mode="html", link_preview=False, buttons=buttons
|
| 315 |
+
)
|
| 316 |
+
]
|
| 317 |
+
await ult.answer(result)
|
| 318 |
+
|
| 319 |
+
|
| 320 |
+
@ultroid_cmd(pattern="update( (.*)|$)")
|
| 321 |
+
async def _(e):
|
| 322 |
+
xx = await e.eor(get_string("upd_1"))
|
| 323 |
+
if e.pattern_match.group(1).strip() and (
|
| 324 |
+
"fast" in e.pattern_match.group(1).strip()
|
| 325 |
+
or "soft" in e.pattern_match.group(1).strip()
|
| 326 |
+
):
|
| 327 |
+
await bash("git pull -f && pip3 install -r requirements.txt")
|
| 328 |
+
await bash("pip3 install -r requirements.txt --break-system-packages")
|
| 329 |
+
call_back()
|
| 330 |
+
await xx.edit(get_string("upd_7"))
|
| 331 |
+
os.execl(sys.executable, "python3", "-m", "pyUltroid")
|
| 332 |
+
# return
|
| 333 |
+
m = await updater()
|
| 334 |
+
branch = (Repo.init()).active_branch
|
| 335 |
+
if m:
|
| 336 |
+
x = await asst.send_file(
|
| 337 |
+
udB.get_key("LOG_CHANNEL"),
|
| 338 |
+
ULTPIC(),
|
| 339 |
+
caption="• **Update Available** •",
|
| 340 |
+
force_document=False,
|
| 341 |
+
buttons=Button.inline("Changelogs", data="changes"),
|
| 342 |
+
)
|
| 343 |
+
Link = x.message_link
|
| 344 |
+
await xx.edit(
|
| 345 |
+
f'<strong><a href="{Link}">[ChangeLogs]</a></strong>',
|
| 346 |
+
parse_mode="html",
|
| 347 |
+
link_preview=False,
|
| 348 |
+
)
|
| 349 |
+
else:
|
| 350 |
+
await xx.edit(
|
| 351 |
+
f'<code>Your BOT is </code><strong>up-to-date</strong><code> with </code><strong><a href="https://github.com/TeamUltroid/Ultroid/tree/{branch}">[{branch}]</a></strong>',
|
| 352 |
+
parse_mode="html",
|
| 353 |
+
link_preview=False,
|
| 354 |
+
)
|
| 355 |
+
|
| 356 |
+
|
| 357 |
+
@callback("updtavail", owner=True)
|
| 358 |
+
async def updava(event):
|
| 359 |
+
await event.delete()
|
| 360 |
+
await asst.send_file(
|
| 361 |
+
udB.get_key("LOG_CHANNEL"),
|
| 362 |
+
ULTPIC(),
|
| 363 |
+
caption="• **Update Available** •",
|
| 364 |
+
force_document=False,
|
| 365 |
+
buttons=Button.inline("Changelogs", data="changes"),
|
| 366 |
+
)
|
plugins/broadcast.py
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
from . import get_help
|
| 10 |
+
|
| 11 |
+
__doc__ = get_help("help_broadcast")
|
| 12 |
+
|
| 13 |
+
import asyncio
|
| 14 |
+
import io
|
| 15 |
+
|
| 16 |
+
from telethon.utils import get_display_name
|
| 17 |
+
|
| 18 |
+
from pyUltroid.dB.base import KeyManager
|
| 19 |
+
|
| 20 |
+
from . import HNDLR, LOGS, eor, get_string, udB, ultroid_bot, ultroid_cmd
|
| 21 |
+
|
| 22 |
+
KeyM = KeyManager("BROADCAST", cast=list)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@ultroid_cmd(
|
| 26 |
+
pattern="addch( (.*)|$)",
|
| 27 |
+
allow_sudo=False,
|
| 28 |
+
)
|
| 29 |
+
async def broadcast_adder(event):
|
| 30 |
+
msgg = event.pattern_match.group(1).strip()
|
| 31 |
+
x = await event.eor(get_string("bd_1"))
|
| 32 |
+
if msgg == "all":
|
| 33 |
+
await x.edit(get_string("bd_2"))
|
| 34 |
+
chats = [
|
| 35 |
+
e.entity
|
| 36 |
+
for e in await event.client.get_dialogs()
|
| 37 |
+
if (e.is_group or e.is_channel)
|
| 38 |
+
]
|
| 39 |
+
new = 0
|
| 40 |
+
for i in chats:
|
| 41 |
+
try:
|
| 42 |
+
if (
|
| 43 |
+
i.broadcast
|
| 44 |
+
and (i.creator or i.admin_rights)
|
| 45 |
+
and not KeyM.contains(i.id)
|
| 46 |
+
):
|
| 47 |
+
new += 1
|
| 48 |
+
cid = f"-100{i.id}"
|
| 49 |
+
KeyM.add(int(cid))
|
| 50 |
+
except Exception as Ex:
|
| 51 |
+
LOGS.exception(Ex)
|
| 52 |
+
await x.edit(get_string("bd_3").format(KeyM.count(), new))
|
| 53 |
+
return
|
| 54 |
+
if event.reply_to_msg_id:
|
| 55 |
+
previous_message = await event.get_reply_message()
|
| 56 |
+
raw_text = previous_message.text
|
| 57 |
+
lines = raw_text.split("\n")
|
| 58 |
+
length = len(lines)
|
| 59 |
+
for line_number in range(1, length - 2):
|
| 60 |
+
channel_id = lines[line_number][4:-1]
|
| 61 |
+
if not KeyM.contains(channel_id):
|
| 62 |
+
KeyM.add(channel_id)
|
| 63 |
+
await x.edit(get_string("bd_4"))
|
| 64 |
+
await asyncio.sleep(3)
|
| 65 |
+
await event.delete()
|
| 66 |
+
return
|
| 67 |
+
chat_id = event.chat_id
|
| 68 |
+
if chat_id == udB.get_key("LOG_CHANNEL"):
|
| 69 |
+
return
|
| 70 |
+
if KeyM.contains(chat_id):
|
| 71 |
+
await x.edit(get_string("bd_6"))
|
| 72 |
+
elif xx := KeyM.add(chat_id):
|
| 73 |
+
await x.edit(get_string("bd_5"))
|
| 74 |
+
else:
|
| 75 |
+
await x.edit(get_string("sf_8"))
|
| 76 |
+
await asyncio.sleep(3)
|
| 77 |
+
await x.delete()
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
@ultroid_cmd(
|
| 81 |
+
pattern="remch( (.*)|$)",
|
| 82 |
+
allow_sudo=False,
|
| 83 |
+
)
|
| 84 |
+
async def broadcast_remover(event):
|
| 85 |
+
chat_id = event.pattern_match.group(1).strip() or event.chat_id
|
| 86 |
+
x = await event.eor(get_string("com_1"))
|
| 87 |
+
if chat_id == "all":
|
| 88 |
+
await x.edit(get_string("bd_8"))
|
| 89 |
+
udB.del_key("BROADCAST")
|
| 90 |
+
await x.edit("Database cleared.")
|
| 91 |
+
return
|
| 92 |
+
if KeyM.contains(chat_id):
|
| 93 |
+
KeyM.remove(chat_id)
|
| 94 |
+
await x.edit(get_string("bd_7"))
|
| 95 |
+
else:
|
| 96 |
+
await x.edit(get_string("bd_9"))
|
| 97 |
+
await asyncio.sleep(3)
|
| 98 |
+
await x.delete()
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
@ultroid_cmd(
|
| 102 |
+
pattern="listchannels$",
|
| 103 |
+
)
|
| 104 |
+
async def list_all(event):
|
| 105 |
+
x = await event.eor(get_string("com_1"))
|
| 106 |
+
channels = KeyM.get()
|
| 107 |
+
num = KeyM.count()
|
| 108 |
+
if not channels:
|
| 109 |
+
return await eor(x, "No chats were added.", time=5)
|
| 110 |
+
msg = "Channels in database:\n"
|
| 111 |
+
for channel in channels:
|
| 112 |
+
name = ""
|
| 113 |
+
try:
|
| 114 |
+
name = get_display_name(await event.client.get_entity(channel))
|
| 115 |
+
except ValueError:
|
| 116 |
+
name = ""
|
| 117 |
+
msg += f"=> **{name}** [`{channel}`]\n"
|
| 118 |
+
msg += f"\nTotal {num} channels."
|
| 119 |
+
if len(msg) > 4096:
|
| 120 |
+
MSG = msg.replace("*", "").replace("`", "")
|
| 121 |
+
with io.BytesIO(str.encode(MSG)) as out_file:
|
| 122 |
+
out_file.name = "channels.txt"
|
| 123 |
+
await event.reply(
|
| 124 |
+
"Channels in Database",
|
| 125 |
+
file=out_file,
|
| 126 |
+
force_document=True,
|
| 127 |
+
allow_cache=False,
|
| 128 |
+
)
|
| 129 |
+
await x.delete()
|
| 130 |
+
else:
|
| 131 |
+
await x.edit(msg)
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
@ultroid_cmd(
|
| 135 |
+
pattern="forward$",
|
| 136 |
+
allow_sudo=False,
|
| 137 |
+
)
|
| 138 |
+
async def forw(event):
|
| 139 |
+
if not event.is_reply:
|
| 140 |
+
return await event.eor(get_string("ex_1"))
|
| 141 |
+
ultroid_bot = event.client
|
| 142 |
+
channels = KeyM.get()
|
| 143 |
+
x = await event.eor("Sending...")
|
| 144 |
+
if not channels:
|
| 145 |
+
return await x.edit(f"Please add channels by using `{HNDLR}add` in them.")
|
| 146 |
+
error_count = 0
|
| 147 |
+
sent_count = 0
|
| 148 |
+
previous_message = await event.get_reply_message()
|
| 149 |
+
error_count = 0
|
| 150 |
+
for channel in channels:
|
| 151 |
+
try:
|
| 152 |
+
await ultroid_bot.forward_messages(channel, previous_message)
|
| 153 |
+
sent_count += 1
|
| 154 |
+
await x.edit(
|
| 155 |
+
f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}",
|
| 156 |
+
)
|
| 157 |
+
except Exception:
|
| 158 |
+
try:
|
| 159 |
+
await ultroid_bot.send_message(
|
| 160 |
+
udB.get_key("LOG_CHANNEL"),
|
| 161 |
+
f"Error in sending at {channel}.",
|
| 162 |
+
)
|
| 163 |
+
except Exception as Em:
|
| 164 |
+
LOGS.info(Em)
|
| 165 |
+
error_count += 1
|
| 166 |
+
await x.edit(
|
| 167 |
+
f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}",
|
| 168 |
+
)
|
| 169 |
+
await x.edit(f"{sent_count} messages sent with {error_count} errors.")
|
| 170 |
+
if error_count > 0:
|
| 171 |
+
await ultroid_bot.send_message(
|
| 172 |
+
udB.get_key("LOG_CHANNEL"), f"{error_count} Errors"
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
@ultroid_cmd(
|
| 177 |
+
pattern="broadcast( (.*)|$)",
|
| 178 |
+
allow_sudo=False,
|
| 179 |
+
)
|
| 180 |
+
async def sending(event):
|
| 181 |
+
x = await event.eor(get_string("com_1"))
|
| 182 |
+
if not event.is_reply:
|
| 183 |
+
return await x.edit(get_string("ex_1"))
|
| 184 |
+
channels = KeyM.get()
|
| 185 |
+
if not channels:
|
| 186 |
+
return await x.edit(f"Please add channels by using `{HNDLR}add` in them.")
|
| 187 |
+
await x.edit("Sending....")
|
| 188 |
+
if event.reply_to_msg_id:
|
| 189 |
+
previous_message = await event.get_reply_message()
|
| 190 |
+
if previous_message.poll:
|
| 191 |
+
return await x.edit(f"Reply `{HNDLR}forward` for polls.")
|
| 192 |
+
if previous_message:
|
| 193 |
+
error_count = 0
|
| 194 |
+
sent_count = 0
|
| 195 |
+
for channel in channels:
|
| 196 |
+
try:
|
| 197 |
+
await ultroid_bot.send_message(channel, previous_message)
|
| 198 |
+
sent_count += 1
|
| 199 |
+
await x.edit(
|
| 200 |
+
f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}",
|
| 201 |
+
)
|
| 202 |
+
except Exception as error:
|
| 203 |
+
await ultroid_bot.send_message(
|
| 204 |
+
udB.get_key("LOG_CHANNEL"),
|
| 205 |
+
f"Error in sending at {channel}.\n\n{error}",
|
| 206 |
+
)
|
| 207 |
+
error_count += 1
|
| 208 |
+
await x.edit(
|
| 209 |
+
f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}",
|
| 210 |
+
)
|
| 211 |
+
await x.edit(f"{sent_count} messages sent with {error_count} errors.")
|
| 212 |
+
if error_count > 0:
|
| 213 |
+
await ultroid_bot.send_message(
|
| 214 |
+
udB.get_key("LOG_CHANNEL"),
|
| 215 |
+
f"{error_count} Errors",
|
| 216 |
+
)
|
plugins/button.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_button")
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
from . import upload_file as uf
|
| 15 |
+
from telethon.utils import pack_bot_file_id
|
| 16 |
+
|
| 17 |
+
from pyUltroid.fns.tools import create_tl_btn, get_msg_button
|
| 18 |
+
|
| 19 |
+
from . import HNDLR, get_string, mediainfo, ultroid_cmd
|
| 20 |
+
from ._inline import something
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@ultroid_cmd(pattern="button")
|
| 24 |
+
async def butt(event):
|
| 25 |
+
media, wut, text = None, None, None
|
| 26 |
+
if event.reply_to:
|
| 27 |
+
wt = await event.get_reply_message()
|
| 28 |
+
if wt.text:
|
| 29 |
+
text = wt.text
|
| 30 |
+
if wt.media:
|
| 31 |
+
wut = mediainfo(wt.media)
|
| 32 |
+
if wut and wut.startswith(("pic", "gif")):
|
| 33 |
+
dl = await wt.download_media()
|
| 34 |
+
media = uf(dl)
|
| 35 |
+
elif wut == "video":
|
| 36 |
+
if wt.media.document.size > 8 * 1000 * 1000:
|
| 37 |
+
return await event.eor(get_string("com_4"), time=5)
|
| 38 |
+
dl = await wt.download_media()
|
| 39 |
+
media = uf(dl)
|
| 40 |
+
os.remove(dl)
|
| 41 |
+
else:
|
| 42 |
+
media = pack_bot_file_id(wt.media)
|
| 43 |
+
try:
|
| 44 |
+
text = event.text.split(maxsplit=1)[1]
|
| 45 |
+
except IndexError:
|
| 46 |
+
if not text:
|
| 47 |
+
return await event.eor(
|
| 48 |
+
f"**Please give some text in correct format.**\n\n`{HNDLR}help button`",
|
| 49 |
+
)
|
| 50 |
+
text, buttons = get_msg_button(text)
|
| 51 |
+
if buttons:
|
| 52 |
+
buttons = create_tl_btn(buttons)
|
| 53 |
+
await something(event, text, media, buttons)
|
| 54 |
+
await event.delete()
|
plugins/calculator.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
from . import get_help
|
| 10 |
+
|
| 11 |
+
__doc__ = get_help("help_calculator")
|
| 12 |
+
|
| 13 |
+
import re
|
| 14 |
+
|
| 15 |
+
from . import Button, asst, callback, get_string, in_pattern, udB, ultroid_cmd
|
| 16 |
+
|
| 17 |
+
CALC = {}
|
| 18 |
+
|
| 19 |
+
m = [
|
| 20 |
+
"AC",
|
| 21 |
+
"C",
|
| 22 |
+
"⌫",
|
| 23 |
+
"%",
|
| 24 |
+
"7",
|
| 25 |
+
"8",
|
| 26 |
+
"9",
|
| 27 |
+
"+",
|
| 28 |
+
"4",
|
| 29 |
+
"5",
|
| 30 |
+
"6",
|
| 31 |
+
"-",
|
| 32 |
+
"1",
|
| 33 |
+
"2",
|
| 34 |
+
"3",
|
| 35 |
+
"x",
|
| 36 |
+
"00",
|
| 37 |
+
"0",
|
| 38 |
+
".",
|
| 39 |
+
"÷",
|
| 40 |
+
]
|
| 41 |
+
tultd = [Button.inline(f"{x}", data=f"calc{x}") for x in m]
|
| 42 |
+
lst = list(zip(tultd[::4], tultd[1::4], tultd[2::4], tultd[3::4]))
|
| 43 |
+
lst.append([Button.inline("=", data="calc=")])
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
@ultroid_cmd(pattern="calc")
|
| 47 |
+
async def icalc(e):
|
| 48 |
+
udB.del_key("calc")
|
| 49 |
+
if e.client._bot:
|
| 50 |
+
return await e.reply(get_string("calc_1"), buttons=lst)
|
| 51 |
+
results = await e.client.inline_query(asst.me.username, "calc")
|
| 52 |
+
await results[0].click(e.chat_id, silent=True, hide_via=True)
|
| 53 |
+
await e.delete()
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
@in_pattern("calc", owner=True)
|
| 57 |
+
async def _(e):
|
| 58 |
+
calc = e.builder.article("Calc", text=get_string("calc_1"), buttons=lst)
|
| 59 |
+
await e.answer([calc])
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
@callback(re.compile("calc(.*)"), owner=True)
|
| 63 |
+
async def _(e):
|
| 64 |
+
x = (e.data_match.group(1)).decode()
|
| 65 |
+
user = e.query.user_id
|
| 66 |
+
get = None
|
| 67 |
+
if x == "AC":
|
| 68 |
+
if CALC.get(user):
|
| 69 |
+
CALC.pop(user)
|
| 70 |
+
await e.edit(
|
| 71 |
+
get_string("calc_1"),
|
| 72 |
+
buttons=[Button.inline(get_string("calc_2"), data="recalc")],
|
| 73 |
+
)
|
| 74 |
+
elif x == "C":
|
| 75 |
+
if CALC.get(user):
|
| 76 |
+
CALC.pop(user)
|
| 77 |
+
await e.answer("cleared")
|
| 78 |
+
elif x == "⌫":
|
| 79 |
+
if CALC.get(user):
|
| 80 |
+
get = CALC[user]
|
| 81 |
+
if get:
|
| 82 |
+
CALC.update({user: get[:-1]})
|
| 83 |
+
await e.answer(str(get[:-1]))
|
| 84 |
+
elif x == "%":
|
| 85 |
+
if CALC.get(user):
|
| 86 |
+
get = CALC[user]
|
| 87 |
+
if get:
|
| 88 |
+
CALC.update({user: f"{get}/100"})
|
| 89 |
+
await e.answer(str(f"{get}/100"))
|
| 90 |
+
elif x == "÷":
|
| 91 |
+
if CALC.get(user):
|
| 92 |
+
get = CALC[user]
|
| 93 |
+
if get:
|
| 94 |
+
CALC.update({user: f"{get}/"})
|
| 95 |
+
await e.answer(str(f"{get}/"))
|
| 96 |
+
elif x == "x":
|
| 97 |
+
if CALC.get(user):
|
| 98 |
+
get = CALC[user]
|
| 99 |
+
if get:
|
| 100 |
+
CALC.update({user: f"{get}*"})
|
| 101 |
+
await e.answer(str(f"{get}*"))
|
| 102 |
+
elif x == "=":
|
| 103 |
+
if CALC.get(user):
|
| 104 |
+
get = CALC[user]
|
| 105 |
+
if get:
|
| 106 |
+
if get.endswith(("*", ".", "/", "-", "+")):
|
| 107 |
+
get = get[:-1]
|
| 108 |
+
out = eval(get)
|
| 109 |
+
try:
|
| 110 |
+
num = float(out)
|
| 111 |
+
await e.answer(f"Answer : {num}", cache_time=0, alert=True)
|
| 112 |
+
except BaseException:
|
| 113 |
+
CALC.pop(user)
|
| 114 |
+
await e.answer(get_string("sf_8"), cache_time=0, alert=True)
|
| 115 |
+
await e.answer("None")
|
| 116 |
+
else:
|
| 117 |
+
if CALC.get(user):
|
| 118 |
+
get = CALC[user]
|
| 119 |
+
if get:
|
| 120 |
+
CALC.update({user: get + x})
|
| 121 |
+
return await e.answer(str(get + x))
|
| 122 |
+
CALC.update({user: x})
|
| 123 |
+
await e.answer(str(x))
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
@callback("recalc", owner=True)
|
| 127 |
+
async def _(e):
|
| 128 |
+
m = [
|
| 129 |
+
"AC",
|
| 130 |
+
"C",
|
| 131 |
+
"⌫",
|
| 132 |
+
"%",
|
| 133 |
+
"7",
|
| 134 |
+
"8",
|
| 135 |
+
"9",
|
| 136 |
+
"+",
|
| 137 |
+
"4",
|
| 138 |
+
"5",
|
| 139 |
+
"6",
|
| 140 |
+
"-",
|
| 141 |
+
"1",
|
| 142 |
+
"2",
|
| 143 |
+
"3",
|
| 144 |
+
"x",
|
| 145 |
+
"00",
|
| 146 |
+
"0",
|
| 147 |
+
".",
|
| 148 |
+
"÷",
|
| 149 |
+
]
|
| 150 |
+
tultd = [Button.inline(f"{x}", data=f"calc{x}") for x in m]
|
| 151 |
+
lst = list(zip(tultd[::4], tultd[1::4], tultd[2::4], tultd[3::4]))
|
| 152 |
+
lst.append([Button.inline("=", data="calc=")])
|
| 153 |
+
await e.edit(get_string("calc_1"), buttons=lst)
|
plugins/channelhacks.py
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
from . import get_help
|
| 8 |
+
|
| 9 |
+
__doc__ = get_help("help_channelhacks")
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
import asyncio
|
| 13 |
+
import io
|
| 14 |
+
|
| 15 |
+
from telethon.errors.rpcerrorlist import FloodWaitError
|
| 16 |
+
from telethon.utils import get_display_name, get_peer_id
|
| 17 |
+
|
| 18 |
+
from pyUltroid.dB.base import KeyManager
|
| 19 |
+
|
| 20 |
+
from . import LOGS, asst, eor, events, get_string, udB, ultroid_bot, ultroid_cmd
|
| 21 |
+
|
| 22 |
+
ERROR = {}
|
| 23 |
+
SourceM = KeyManager("CH_SOURCE", cast=list)
|
| 24 |
+
DestiM = KeyManager("CH_DESTINATIONS", cast=list)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
async def autopost_func(e):
|
| 28 |
+
if not udB.get_key("AUTOPOST"):
|
| 29 |
+
return
|
| 30 |
+
x = SourceM.get()
|
| 31 |
+
th = await e.get_chat()
|
| 32 |
+
if get_peer_id(th) not in x:
|
| 33 |
+
return
|
| 34 |
+
y = DestiM.get()
|
| 35 |
+
for ys in y:
|
| 36 |
+
try:
|
| 37 |
+
await e.client.send_message(int(ys), e.message)
|
| 38 |
+
except Exception as ex:
|
| 39 |
+
try:
|
| 40 |
+
ERROR[str(ex)]
|
| 41 |
+
except KeyError:
|
| 42 |
+
ERROR.update({str(ex): ex})
|
| 43 |
+
Error = f"**Error on AUTOPOST**\n\n`{ex}`"
|
| 44 |
+
await asst.send_message(udB.get_key("LOG_CHANNEL"), Error)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
@ultroid_cmd(pattern="shift (.*)")
|
| 48 |
+
async def _(e):
|
| 49 |
+
x = e.pattern_match.group(1).strip()
|
| 50 |
+
z = await e.eor(get_string("com_1"))
|
| 51 |
+
a, b = x.split("|")
|
| 52 |
+
try:
|
| 53 |
+
c = await e.client.parse_id(a)
|
| 54 |
+
except Exception:
|
| 55 |
+
await z.edit(get_string("cha_1"))
|
| 56 |
+
return
|
| 57 |
+
try:
|
| 58 |
+
d = await e.client.parse_id(b)
|
| 59 |
+
except Exception as er:
|
| 60 |
+
LOGS.exception(er)
|
| 61 |
+
await z.edit(get_string("cha_1"))
|
| 62 |
+
return
|
| 63 |
+
async for msg in e.client.iter_messages(int(c), reverse=True, limit=None):
|
| 64 |
+
try:
|
| 65 |
+
await asyncio.sleep(2)
|
| 66 |
+
await e.client.send_message(int(d), msg)
|
| 67 |
+
except FloodWaitError as er:
|
| 68 |
+
await asyncio.sleep(er.seconds + 5)
|
| 69 |
+
await e.client.send_message(int(d), msg)
|
| 70 |
+
except BaseException as er:
|
| 71 |
+
LOGS.exception(er)
|
| 72 |
+
await z.edit("Done")
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
@ultroid_cmd(pattern="asource (.*)")
|
| 76 |
+
async def source(e):
|
| 77 |
+
if x := e.pattern_match.group(1).strip():
|
| 78 |
+
try:
|
| 79 |
+
y = await e.client.parse_id(x)
|
| 80 |
+
except Exception as er:
|
| 81 |
+
LOGS.exception(er)
|
| 82 |
+
return
|
| 83 |
+
else:
|
| 84 |
+
y = e.chat_id
|
| 85 |
+
if not SourceM.contains(y):
|
| 86 |
+
SourceM.add(y)
|
| 87 |
+
await e.eor(get_string("cha_2"))
|
| 88 |
+
ultroid_bot.add_handler(autopost_func, events.NewMessage())
|
| 89 |
+
else:
|
| 90 |
+
await e.eor(get_string("cha_3"))
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
@ultroid_cmd(pattern="dsource( (.*)|$)")
|
| 94 |
+
async def dd(event):
|
| 95 |
+
chat_id = event.pattern_match.group(1).strip()
|
| 96 |
+
x = await event.eor(get_string("com_1"))
|
| 97 |
+
if chat_id == "all":
|
| 98 |
+
await x.edit(get_string("bd_8"))
|
| 99 |
+
udB.del_key("CH_SOURCE")
|
| 100 |
+
await x.edit(get_string("cha_4"))
|
| 101 |
+
return
|
| 102 |
+
if chat_id:
|
| 103 |
+
try:
|
| 104 |
+
y = await event.client.parse_id(chat_id)
|
| 105 |
+
except Exception as er:
|
| 106 |
+
LOGS.exception(er)
|
| 107 |
+
return
|
| 108 |
+
else:
|
| 109 |
+
y = event.chat_id
|
| 110 |
+
if SourceM.contains(y):
|
| 111 |
+
SourceM.remove(y)
|
| 112 |
+
await eor(x, get_string("cha_5"), time=5)
|
| 113 |
+
else:
|
| 114 |
+
await eor(x, "Source channel is already removed from database. ", time=3)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
@ultroid_cmd(pattern="listsource")
|
| 118 |
+
async def list_all(event):
|
| 119 |
+
x = await event.eor(get_string("com_1"))
|
| 120 |
+
num = SourceM.count()
|
| 121 |
+
if not num:
|
| 122 |
+
return await eor(x, "No chats were added.", time=5)
|
| 123 |
+
msg = get_string("cha_8")
|
| 124 |
+
channels = SourceM.get()
|
| 125 |
+
for channel in channels:
|
| 126 |
+
name = ""
|
| 127 |
+
try:
|
| 128 |
+
name = get_display_name(await event.client.get_entity(int(channel)))
|
| 129 |
+
except BaseException:
|
| 130 |
+
name = ""
|
| 131 |
+
msg += f"\n=> **{name}** [`{channel}`]"
|
| 132 |
+
msg += f"\nTotal {num} channels."
|
| 133 |
+
if len(msg) > 4096:
|
| 134 |
+
MSG = msg.replace("*", "").replace("`", "")
|
| 135 |
+
with io.BytesIO(str.encode(MSG)) as out_file:
|
| 136 |
+
out_file.name = "channels.txt"
|
| 137 |
+
await event.reply(
|
| 138 |
+
"Channels in database",
|
| 139 |
+
file=out_file,
|
| 140 |
+
force_document=True,
|
| 141 |
+
allow_cache=False,
|
| 142 |
+
)
|
| 143 |
+
await x.delete()
|
| 144 |
+
else:
|
| 145 |
+
await x.edit(msg)
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
@ultroid_cmd(pattern="adest (.*)")
|
| 149 |
+
async def destination(e):
|
| 150 |
+
if x := e.pattern_match.group(1).strip():
|
| 151 |
+
try:
|
| 152 |
+
y = await e.client.parse_id(x)
|
| 153 |
+
except Exception as er:
|
| 154 |
+
LOGS.exception(er)
|
| 155 |
+
return
|
| 156 |
+
else:
|
| 157 |
+
y = e.chat_id
|
| 158 |
+
if not DestiM.contains(y):
|
| 159 |
+
DestiM.add(y)
|
| 160 |
+
await e.eor("Destination added succesfully")
|
| 161 |
+
else:
|
| 162 |
+
await e.eor("Destination channel already added")
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
@ultroid_cmd(pattern="ddest( (.*)|$)")
|
| 166 |
+
async def dd(event):
|
| 167 |
+
chat_id = event.pattern_match.group(1).strip()
|
| 168 |
+
x = await event.eor(get_string("com_1"))
|
| 169 |
+
if chat_id == "all":
|
| 170 |
+
await x.edit(get_string("bd_8"))
|
| 171 |
+
udB.del_key("CH_DESTINATION")
|
| 172 |
+
await x.edit("Destinations database cleared.")
|
| 173 |
+
return
|
| 174 |
+
if chat_id:
|
| 175 |
+
try:
|
| 176 |
+
y = await event.client.parse_id(chat_id)
|
| 177 |
+
except Exception as er:
|
| 178 |
+
LOGS.exception(er)
|
| 179 |
+
return
|
| 180 |
+
else:
|
| 181 |
+
y = event.chat_id
|
| 182 |
+
if DestiM.contains(y):
|
| 183 |
+
DestiM.remove(y)
|
| 184 |
+
await eor(x, "Destination removed from database")
|
| 185 |
+
else:
|
| 186 |
+
await eor(x, "Destination channel is already removed from database. ", time=5)
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
@ultroid_cmd(pattern="listdest")
|
| 190 |
+
async def list_all(event):
|
| 191 |
+
ultroid_bot = event.client
|
| 192 |
+
x = await event.eor(get_string("com_1"))
|
| 193 |
+
channels = DestiM.get()
|
| 194 |
+
num = len(channels)
|
| 195 |
+
if not num:
|
| 196 |
+
return await eor(x, "No chats were added.", time=5)
|
| 197 |
+
msg = get_string("cha_7")
|
| 198 |
+
for channel in channels:
|
| 199 |
+
name = ""
|
| 200 |
+
try:
|
| 201 |
+
name = get_display_name(await ultroid_bot.get_entity(int(channel)))
|
| 202 |
+
except BaseException:
|
| 203 |
+
name = ""
|
| 204 |
+
msg += f"\n=> **{name}** [`{channel}`]"
|
| 205 |
+
msg += f"\nTotal {num} channels."
|
| 206 |
+
if len(msg) > 4096:
|
| 207 |
+
MSG = msg.replace("*", "").replace("`", "")
|
| 208 |
+
with io.BytesIO(str.encode(MSG)) as out_file:
|
| 209 |
+
out_file.name = "channels.txt"
|
| 210 |
+
await ultroid_bot.send_file(
|
| 211 |
+
event.chat_id,
|
| 212 |
+
out_file,
|
| 213 |
+
force_document=True,
|
| 214 |
+
allow_cache=False,
|
| 215 |
+
caption="Destination channels in database",
|
| 216 |
+
reply_to=event,
|
| 217 |
+
)
|
| 218 |
+
await x.delete()
|
| 219 |
+
else:
|
| 220 |
+
await x.edit(msg)
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
if udB.get_key("AUTOPOST"):
|
| 224 |
+
ultroid_bot.add_handler(autopost_func, events.NewMessage())
|
plugins/chatbot.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_chatbot")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
from pyUltroid.fns.tools import get_chatbot_reply
|
| 14 |
+
|
| 15 |
+
from . import LOGS, eod, get_string, inline_mention, udB, ultroid_cmd
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
@ultroid_cmd(pattern="repai")
|
| 19 |
+
async def im_lonely_chat_with_me(event):
|
| 20 |
+
if event.reply_to:
|
| 21 |
+
message = (await event.get_reply_message()).message
|
| 22 |
+
else:
|
| 23 |
+
try:
|
| 24 |
+
message = event.text.split(" ", 1)[1]
|
| 25 |
+
except IndexError:
|
| 26 |
+
return await eod(event, get_string("tban_1"), time=10)
|
| 27 |
+
reply_ = await get_chatbot_reply(message=message)
|
| 28 |
+
await event.eor(reply_)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
@ultroid_cmd(pattern="addai")
|
| 32 |
+
async def add_chatBot(event):
|
| 33 |
+
await chat_bot_fn(event, type_="add")
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
@ultroid_cmd(pattern="remai")
|
| 37 |
+
async def rem_chatBot(event):
|
| 38 |
+
await chat_bot_fn(event, type_="remov")
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
@ultroid_cmd(pattern="listai")
|
| 42 |
+
async def lister(event):
|
| 43 |
+
key = udB.get_key("CHATBOT_USERS") or {}
|
| 44 |
+
users = key.get(event.chat_id, [])
|
| 45 |
+
if not users:
|
| 46 |
+
return await event.eor(get_string("chab_2"), time=5)
|
| 47 |
+
msg = "**Total List Of AI Enabled Users In This Chat :**\n\n"
|
| 48 |
+
for i in users:
|
| 49 |
+
try:
|
| 50 |
+
user = await event.client.get_entity(int(i))
|
| 51 |
+
user = inline_mention(user)
|
| 52 |
+
except BaseException:
|
| 53 |
+
user = f"`{i}`"
|
| 54 |
+
msg += f"• {user}\n"
|
| 55 |
+
await event.eor(msg, link_preview=False)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
async def chat_bot_fn(event, type_):
|
| 59 |
+
if event.reply_to:
|
| 60 |
+
user_ = (await event.get_reply_message()).sender
|
| 61 |
+
else:
|
| 62 |
+
temp = event.text.split(maxsplit=1)
|
| 63 |
+
try:
|
| 64 |
+
user_ = await event.client.get_entity(await event.client.parse_id(temp[1]))
|
| 65 |
+
except BaseException as er:
|
| 66 |
+
LOGS.exception(er)
|
| 67 |
+
user_ = event.chat if event.is_private else None
|
| 68 |
+
if not user_:
|
| 69 |
+
return await eod(
|
| 70 |
+
event,
|
| 71 |
+
get_string("chab_1"),
|
| 72 |
+
)
|
| 73 |
+
key = udB.get_key("CHATBOT_USERS") or {}
|
| 74 |
+
chat = event.chat_id
|
| 75 |
+
user = user_.id
|
| 76 |
+
if type_ == "add":
|
| 77 |
+
if key.get(chat):
|
| 78 |
+
if user not in key[chat]:
|
| 79 |
+
key[chat].append(user)
|
| 80 |
+
else:
|
| 81 |
+
key.update({chat: [user]})
|
| 82 |
+
elif type_ == "remov":
|
| 83 |
+
if key.get(chat):
|
| 84 |
+
if user in key[chat]:
|
| 85 |
+
key[chat].remove(user)
|
| 86 |
+
if chat in key and not key[chat]:
|
| 87 |
+
del key[chat]
|
| 88 |
+
udB.set_key("CHATBOT_USERS", key)
|
| 89 |
+
await event.eor(f"**ChatBot:**\n{type_}ed {inline_mention(user_)}")
|
plugins/chats.py
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
from . import get_help
|
| 8 |
+
|
| 9 |
+
__doc__ = get_help("help_chats")
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
from telethon.errors import ChatAdminRequiredError as no_admin
|
| 13 |
+
from telethon.tl.functions.channels import (
|
| 14 |
+
CreateChannelRequest,
|
| 15 |
+
DeleteChannelRequest,
|
| 16 |
+
EditPhotoRequest,
|
| 17 |
+
GetFullChannelRequest,
|
| 18 |
+
UpdateUsernameRequest,
|
| 19 |
+
)
|
| 20 |
+
from telethon.tl.functions.messages import (
|
| 21 |
+
CreateChatRequest,
|
| 22 |
+
ExportChatInviteRequest,
|
| 23 |
+
GetFullChatRequest,
|
| 24 |
+
)
|
| 25 |
+
from telethon.tl.types import (
|
| 26 |
+
ChannelParticipantsKicked,
|
| 27 |
+
User,
|
| 28 |
+
UserStatusEmpty,
|
| 29 |
+
UserStatusLastMonth,
|
| 30 |
+
UserStatusLastWeek,
|
| 31 |
+
UserStatusOffline,
|
| 32 |
+
UserStatusOnline,
|
| 33 |
+
UserStatusRecently,
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
from . import HNDLR, LOGS, asst, con, get_string, mediainfo, os, types, udB, ultroid_cmd
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
@ultroid_cmd(
|
| 40 |
+
pattern="delchat",
|
| 41 |
+
groups_only=True,
|
| 42 |
+
)
|
| 43 |
+
async def _(e):
|
| 44 |
+
xx = await e.eor(get_string("com_1"))
|
| 45 |
+
try:
|
| 46 |
+
match = e.text.split(" ", maxsplit=1)[1]
|
| 47 |
+
chat = await e.client.parse_id(match)
|
| 48 |
+
except IndexError:
|
| 49 |
+
chat = e.chat_id
|
| 50 |
+
try:
|
| 51 |
+
await e.client(DeleteChannelRequest(chat))
|
| 52 |
+
except TypeError:
|
| 53 |
+
return await xx.eor(get_string("chats_1"), time=10)
|
| 54 |
+
except no_admin:
|
| 55 |
+
return await xx.eor(get_string("chats_2"), time=10)
|
| 56 |
+
await e.client.send_message(
|
| 57 |
+
int(udB.get_key("LOG_CHANNEL")), get_string("chats_6").format(e.chat_id)
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
@ultroid_cmd(
|
| 62 |
+
pattern="getlink( (.*)|$)",
|
| 63 |
+
groups_only=True,
|
| 64 |
+
manager=True,
|
| 65 |
+
)
|
| 66 |
+
async def _(e):
|
| 67 |
+
reply = await e.get_reply_message()
|
| 68 |
+
match = e.pattern_match.group(1).strip()
|
| 69 |
+
if reply and not isinstance(reply.sender, User):
|
| 70 |
+
chat = await reply.get_sender()
|
| 71 |
+
else:
|
| 72 |
+
chat = await e.get_chat()
|
| 73 |
+
if hasattr(chat, "username") and chat.username:
|
| 74 |
+
return await e.eor(f"Username: @{chat.username}")
|
| 75 |
+
request, usage, title, link = None, None, None, None
|
| 76 |
+
if match:
|
| 77 |
+
split = match.split(maxsplit=1)
|
| 78 |
+
request = split[0] in ["r", "request"]
|
| 79 |
+
title = "Created by Ultroid"
|
| 80 |
+
if len(split) > 1:
|
| 81 |
+
match = split[1]
|
| 82 |
+
spli = match.split(maxsplit=1)
|
| 83 |
+
if spli[0].isdigit():
|
| 84 |
+
usage = int(spli[0])
|
| 85 |
+
if len(spli) > 1:
|
| 86 |
+
title = spli[1]
|
| 87 |
+
elif not request:
|
| 88 |
+
if match.isdigit():
|
| 89 |
+
usage = int(match)
|
| 90 |
+
else:
|
| 91 |
+
title = match
|
| 92 |
+
if request and usage:
|
| 93 |
+
usage = 0
|
| 94 |
+
if request or title:
|
| 95 |
+
try:
|
| 96 |
+
r = await e.client(
|
| 97 |
+
ExportChatInviteRequest(
|
| 98 |
+
e.chat_id,
|
| 99 |
+
request_needed=request,
|
| 100 |
+
usage_limit=usage,
|
| 101 |
+
title=title,
|
| 102 |
+
),
|
| 103 |
+
)
|
| 104 |
+
except no_admin:
|
| 105 |
+
return await e.eor(get_string("chats_2"), time=10)
|
| 106 |
+
link = r.link
|
| 107 |
+
else:
|
| 108 |
+
if isinstance(chat, types.Chat):
|
| 109 |
+
FC = await e.client(GetFullChatRequest(chat.id))
|
| 110 |
+
elif isinstance(chat, types.Channel):
|
| 111 |
+
FC = await e.client(GetFullChannelRequest(chat.id))
|
| 112 |
+
else:
|
| 113 |
+
return
|
| 114 |
+
Inv = FC.full_chat.exported_invite
|
| 115 |
+
if Inv and not Inv.revoked:
|
| 116 |
+
link = Inv.link
|
| 117 |
+
if link:
|
| 118 |
+
return await e.eor(f"Link:- {link}")
|
| 119 |
+
await e.eor("`Failed to getlink!\nSeems like link is inaccessible to you...`")
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
@ultroid_cmd(
|
| 123 |
+
pattern="create (b|g|c)(?: |$)(.*)",
|
| 124 |
+
)
|
| 125 |
+
async def _(e):
|
| 126 |
+
type_of_group = e.pattern_match.group(1).strip()
|
| 127 |
+
group_name = e.pattern_match.group(2)
|
| 128 |
+
username = None
|
| 129 |
+
if " ; " in group_name:
|
| 130 |
+
group_ = group_name.split(" ; ", maxsplit=1)
|
| 131 |
+
group_name = group_[0]
|
| 132 |
+
username = group_[1]
|
| 133 |
+
xx = await e.eor(get_string("com_1"))
|
| 134 |
+
if type_of_group == "b":
|
| 135 |
+
try:
|
| 136 |
+
r = await e.client(
|
| 137 |
+
CreateChatRequest(
|
| 138 |
+
users=[asst.me.username],
|
| 139 |
+
title=group_name,
|
| 140 |
+
),
|
| 141 |
+
)
|
| 142 |
+
created_chat_id = r.chats[0].id
|
| 143 |
+
result = await e.client(
|
| 144 |
+
ExportChatInviteRequest(
|
| 145 |
+
peer=created_chat_id,
|
| 146 |
+
),
|
| 147 |
+
)
|
| 148 |
+
await xx.edit(
|
| 149 |
+
get_string("chats_4").format(group_name, result.link),
|
| 150 |
+
link_preview=False,
|
| 151 |
+
)
|
| 152 |
+
except Exception as ex:
|
| 153 |
+
await xx.edit(str(ex))
|
| 154 |
+
elif type_of_group in ["g", "c"]:
|
| 155 |
+
try:
|
| 156 |
+
r = await e.client(
|
| 157 |
+
CreateChannelRequest(
|
| 158 |
+
title=group_name,
|
| 159 |
+
about=get_string("chats_5"),
|
| 160 |
+
megagroup=type_of_group != "c",
|
| 161 |
+
)
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
created_chat_id = r.chats[0].id
|
| 165 |
+
if username:
|
| 166 |
+
await e.client(UpdateUsernameRequest(created_chat_id, username))
|
| 167 |
+
result = f"https://t.me/{username}"
|
| 168 |
+
else:
|
| 169 |
+
result = (
|
| 170 |
+
await e.client(
|
| 171 |
+
ExportChatInviteRequest(
|
| 172 |
+
peer=created_chat_id,
|
| 173 |
+
),
|
| 174 |
+
)
|
| 175 |
+
).link
|
| 176 |
+
await xx.edit(
|
| 177 |
+
get_string("chats_6").format(f"[{group_name}]({result})"),
|
| 178 |
+
link_preview=False,
|
| 179 |
+
)
|
| 180 |
+
except Exception as ex:
|
| 181 |
+
await xx.edit(str(ex))
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
# ---------------------------------------------------------------- #
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
@ultroid_cmd(
|
| 188 |
+
pattern="setgpic( (.*)|$)", admins_only=True, manager=True, require="change_info"
|
| 189 |
+
)
|
| 190 |
+
async def _(ult):
|
| 191 |
+
if not ult.is_reply:
|
| 192 |
+
return await ult.eor("`Reply to a Media..`", time=5)
|
| 193 |
+
match = ult.pattern_match.group(1).strip()
|
| 194 |
+
if not ult.client._bot and match:
|
| 195 |
+
try:
|
| 196 |
+
chat = await ult.client.parse_id(match)
|
| 197 |
+
except Exception as ok:
|
| 198 |
+
return await ult.eor(str(ok))
|
| 199 |
+
else:
|
| 200 |
+
chat = ult.chat_id
|
| 201 |
+
reply = await ult.get_reply_message()
|
| 202 |
+
if reply.photo or reply.sticker or reply.video:
|
| 203 |
+
replfile = await reply.download_media()
|
| 204 |
+
elif reply.document and reply.document.thumbs:
|
| 205 |
+
replfile = await reply.download_media(thumb=-1)
|
| 206 |
+
else:
|
| 207 |
+
return await ult.eor("Reply to a Photo or Video..")
|
| 208 |
+
mediain = mediainfo(reply.media)
|
| 209 |
+
if "animated" in mediain:
|
| 210 |
+
replfile = await con.convert(replfile, convert_to="mp4")
|
| 211 |
+
else:
|
| 212 |
+
replfile = await con.convert(
|
| 213 |
+
replfile, outname="chatphoto", allowed_formats=["jpg", "png", "mp4"]
|
| 214 |
+
)
|
| 215 |
+
file = await ult.client.upload_file(replfile)
|
| 216 |
+
try:
|
| 217 |
+
if "pic" not in mediain:
|
| 218 |
+
file = types.InputChatUploadedPhoto(video=file)
|
| 219 |
+
await ult.client(EditPhotoRequest(chat, file))
|
| 220 |
+
await ult.eor("`Group Photo has Successfully Changed !`", time=5)
|
| 221 |
+
except Exception as ex:
|
| 222 |
+
await ult.eor(f"Error occured.\n`{str(ex)}`", time=5)
|
| 223 |
+
os.remove(replfile)
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
@ultroid_cmd(
|
| 227 |
+
pattern="delgpic( (.*)|$)", admins_only=True, manager=True, require="change_info"
|
| 228 |
+
)
|
| 229 |
+
async def _(ult):
|
| 230 |
+
match = ult.pattern_match.group(1).strip()
|
| 231 |
+
chat = ult.chat_id
|
| 232 |
+
if not ult.client._bot and match:
|
| 233 |
+
chat = match
|
| 234 |
+
try:
|
| 235 |
+
await ult.client(EditPhotoRequest(chat, types.InputChatPhotoEmpty()))
|
| 236 |
+
text = "`Removed Chat Photo..`"
|
| 237 |
+
except Exception as E:
|
| 238 |
+
text = str(E)
|
| 239 |
+
return await ult.eor(text, time=5)
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
@ultroid_cmd(pattern="unbanall$", manager=True, admins_only=True, require="ban_users")
|
| 243 |
+
async def _(event):
|
| 244 |
+
xx = await event.eor("Searching Participant Lists.")
|
| 245 |
+
p = 0
|
| 246 |
+
title = (await event.get_chat()).title
|
| 247 |
+
async for i in event.client.iter_participants(
|
| 248 |
+
event.chat_id,
|
| 249 |
+
filter=ChannelParticipantsKicked,
|
| 250 |
+
aggressive=True,
|
| 251 |
+
):
|
| 252 |
+
try:
|
| 253 |
+
await event.client.edit_permissions(event.chat_id, i, view_messages=True)
|
| 254 |
+
p += 1
|
| 255 |
+
except no_admin:
|
| 256 |
+
pass
|
| 257 |
+
except BaseException as er:
|
| 258 |
+
LOGS.exception(er)
|
| 259 |
+
await xx.eor(f"{title}: {p} unbanned", time=5)
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
@ultroid_cmd(
|
| 263 |
+
pattern="rmusers( (.*)|$)",
|
| 264 |
+
groups_only=True,
|
| 265 |
+
admins_only=True,
|
| 266 |
+
fullsudo=True,
|
| 267 |
+
)
|
| 268 |
+
async def _(event):
|
| 269 |
+
xx = await event.eor(get_string("com_1"))
|
| 270 |
+
input_str = event.pattern_match.group(1).strip()
|
| 271 |
+
p, a, b, c, d, m, n, y, w, o, q, r = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
| 272 |
+
async for i in event.client.iter_participants(event.chat_id):
|
| 273 |
+
p += 1 # Total Count
|
| 274 |
+
if isinstance(i.status, UserStatusEmpty):
|
| 275 |
+
if "empty" in input_str:
|
| 276 |
+
try:
|
| 277 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 278 |
+
c += 1
|
| 279 |
+
except BaseException:
|
| 280 |
+
pass
|
| 281 |
+
else:
|
| 282 |
+
y += 1
|
| 283 |
+
if isinstance(i.status, UserStatusLastMonth):
|
| 284 |
+
if "month" in input_str:
|
| 285 |
+
try:
|
| 286 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 287 |
+
c += 1
|
| 288 |
+
except BaseException:
|
| 289 |
+
pass
|
| 290 |
+
else:
|
| 291 |
+
m += 1
|
| 292 |
+
if isinstance(i.status, UserStatusLastWeek):
|
| 293 |
+
if "week" in input_str:
|
| 294 |
+
try:
|
| 295 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 296 |
+
c += 1
|
| 297 |
+
except BaseException:
|
| 298 |
+
pass
|
| 299 |
+
else:
|
| 300 |
+
w += 1
|
| 301 |
+
if isinstance(i.status, UserStatusOffline):
|
| 302 |
+
if "offline" in input_str:
|
| 303 |
+
try:
|
| 304 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 305 |
+
c += 1
|
| 306 |
+
except BaseException:
|
| 307 |
+
pass
|
| 308 |
+
else:
|
| 309 |
+
o += 1
|
| 310 |
+
if isinstance(i.status, UserStatusOnline):
|
| 311 |
+
if "online" in input_str:
|
| 312 |
+
try:
|
| 313 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 314 |
+
c += 1
|
| 315 |
+
except BaseException:
|
| 316 |
+
pass
|
| 317 |
+
else:
|
| 318 |
+
q += 1
|
| 319 |
+
if isinstance(i.status, UserStatusRecently):
|
| 320 |
+
if "recently" in input_str:
|
| 321 |
+
try:
|
| 322 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 323 |
+
c += 1
|
| 324 |
+
except BaseException:
|
| 325 |
+
pass
|
| 326 |
+
else:
|
| 327 |
+
r += 1
|
| 328 |
+
if i.bot:
|
| 329 |
+
if "bot" in input_str:
|
| 330 |
+
try:
|
| 331 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 332 |
+
c += 1
|
| 333 |
+
except BaseException:
|
| 334 |
+
pass
|
| 335 |
+
else:
|
| 336 |
+
b += 1
|
| 337 |
+
elif i.deleted:
|
| 338 |
+
if "deleted" in input_str:
|
| 339 |
+
try:
|
| 340 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 341 |
+
c += 1
|
| 342 |
+
except BaseException:
|
| 343 |
+
pass
|
| 344 |
+
else:
|
| 345 |
+
d += 1
|
| 346 |
+
elif i.status is None:
|
| 347 |
+
if "none" in input_str:
|
| 348 |
+
try:
|
| 349 |
+
await event.client.kick_participant(event.chat_id, i)
|
| 350 |
+
c += 1
|
| 351 |
+
except BaseException:
|
| 352 |
+
pass
|
| 353 |
+
else:
|
| 354 |
+
n += 1
|
| 355 |
+
if input_str:
|
| 356 |
+
required_string = f"**>> Kicked** `{c} / {p}` **users**\n\n"
|
| 357 |
+
else:
|
| 358 |
+
required_string = f"**>> Total** `{p}` **users**\n\n"
|
| 359 |
+
required_string += f" `{HNDLR}rmusers deleted` **••** `{d}`\n"
|
| 360 |
+
required_string += f" `{HNDLR}rmusers empty` **••** `{y}`\n"
|
| 361 |
+
required_string += f" `{HNDLR}rmusers month` **••** `{m}`\n"
|
| 362 |
+
required_string += f" `{HNDLR}rmusers week` **••** `{w}`\n"
|
| 363 |
+
required_string += f" `{HNDLR}rmusers offline` **••** `{o}`\n"
|
| 364 |
+
required_string += f" `{HNDLR}rmusers online` **••** `{q}`\n"
|
| 365 |
+
required_string += f" `{HNDLR}rmusers recently` **••** `{r}`\n"
|
| 366 |
+
required_string += f" `{HNDLR}rmusers bot` **••** `{b}`\n"
|
| 367 |
+
required_string += f" `{HNDLR}rmusers none` **••** `{n}`"
|
| 368 |
+
await xx.eor(required_string)
|
plugins/cleanaction.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_cleanaction")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
from telethon.utils import get_display_name
|
| 14 |
+
|
| 15 |
+
from . import get_string, udB, ultroid_cmd
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
@ultroid_cmd(pattern="addclean$", admins_only=True)
|
| 19 |
+
async def _(e):
|
| 20 |
+
key = udB.get_key("CLEANCHAT") or []
|
| 21 |
+
if e.chat_id in key:
|
| 22 |
+
return await eod(e, get_string("clan_5"))
|
| 23 |
+
key.append(e.chat_id)
|
| 24 |
+
udB.set_key("CLEANCHAT", key)
|
| 25 |
+
await e.eor(get_string("clan_1"), time=5)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@ultroid_cmd(pattern="remclean$")
|
| 29 |
+
async def _(e):
|
| 30 |
+
key = udB.get_key("CLEANCHAT") or []
|
| 31 |
+
if e.chat_id in key:
|
| 32 |
+
key.remove(e.chat_id)
|
| 33 |
+
udB.set_key("CLEANCHAT", key)
|
| 34 |
+
await e.eor(get_string("clan_2"), time=5)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
@ultroid_cmd(pattern="listclean$")
|
| 38 |
+
async def _(e):
|
| 39 |
+
if k := udB.get_key("CLEANCHAT"):
|
| 40 |
+
o = ""
|
| 41 |
+
for x in k:
|
| 42 |
+
try:
|
| 43 |
+
title = get_display_name(await e.client.get_entity(x))
|
| 44 |
+
except BaseException:
|
| 45 |
+
title = get_string("clan_3")
|
| 46 |
+
o += f"{x} {title}\n"
|
| 47 |
+
return await e.eor(o)
|
| 48 |
+
await e.eor(get_string("clan_4"), time=5)
|
plugins/compressor.py
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_compressor")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
import asyncio
|
| 14 |
+
import os
|
| 15 |
+
import re
|
| 16 |
+
import time
|
| 17 |
+
from datetime import datetime as dt
|
| 18 |
+
|
| 19 |
+
from telethon.errors.rpcerrorlist import MessageNotModifiedError
|
| 20 |
+
from telethon.tl.types import DocumentAttributeVideo
|
| 21 |
+
|
| 22 |
+
from pyUltroid.fns.tools import metadata
|
| 23 |
+
|
| 24 |
+
from . import (
|
| 25 |
+
ULTConfig,
|
| 26 |
+
bash,
|
| 27 |
+
downloader,
|
| 28 |
+
get_string,
|
| 29 |
+
humanbytes,
|
| 30 |
+
math,
|
| 31 |
+
mediainfo,
|
| 32 |
+
time_formatter,
|
| 33 |
+
ultroid_cmd,
|
| 34 |
+
uploader,
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@ultroid_cmd(pattern="compress( (.*)|$)")
|
| 39 |
+
async def _(e):
|
| 40 |
+
cr = e.pattern_match.group(1).strip()
|
| 41 |
+
crf = 27
|
| 42 |
+
to_stream = False
|
| 43 |
+
if cr:
|
| 44 |
+
k = e.text.split()
|
| 45 |
+
if len(k) == 2:
|
| 46 |
+
crf = int(k[1]) if k[1].isdigit() else 27
|
| 47 |
+
elif len(k) > 2:
|
| 48 |
+
crf = int(k[1]) if k[1].isdigit() else 27
|
| 49 |
+
to_stream = "stream" in k[2]
|
| 50 |
+
vido = await e.get_reply_message()
|
| 51 |
+
if vido and vido.media and "video" in mediainfo(vido.media):
|
| 52 |
+
if hasattr(vido.media, "document"):
|
| 53 |
+
vfile = vido.media.document
|
| 54 |
+
name = vido.file.name
|
| 55 |
+
else:
|
| 56 |
+
vfile = vido.media
|
| 57 |
+
name = ""
|
| 58 |
+
if not name:
|
| 59 |
+
name = "video_" + dt.now().isoformat("_", "seconds") + ".mp4"
|
| 60 |
+
xxx = await e.eor(get_string("audiotools_5"))
|
| 61 |
+
c_time = time.time()
|
| 62 |
+
file = await downloader(
|
| 63 |
+
f"resources/downloads/{name}",
|
| 64 |
+
vfile,
|
| 65 |
+
xxx,
|
| 66 |
+
c_time,
|
| 67 |
+
f"Downloading {name}...",
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
o_size = os.path.getsize(file.name)
|
| 71 |
+
d_time = time.time()
|
| 72 |
+
diff = time_formatter((d_time - c_time) * 1000)
|
| 73 |
+
file_name = (file.name).split("/")[-1]
|
| 74 |
+
out = file_name.replace(file_name.split(".")[-1], "compressed.mkv")
|
| 75 |
+
await xxx.edit(
|
| 76 |
+
f"`Downloaded {file.name} of {humanbytes(o_size)} in {diff}.\nNow Compressing...`"
|
| 77 |
+
)
|
| 78 |
+
x, y = await bash(
|
| 79 |
+
f'mediainfo --fullscan """{file.name}""" | grep "Frame count"'
|
| 80 |
+
)
|
| 81 |
+
if y and y.endswith("NOT_FOUND"):
|
| 82 |
+
return await xxx.edit(f"ERROR: `{y}`")
|
| 83 |
+
total_frames = x.split(":")[1].split("\n")[0]
|
| 84 |
+
progress = f"progress-{c_time}.txt"
|
| 85 |
+
with open(progress, "w"):
|
| 86 |
+
pass
|
| 87 |
+
proce = await asyncio.create_subprocess_shell(
|
| 88 |
+
f'ffmpeg -hide_banner -loglevel quiet -progress {progress} -i """{file.name}""" -preset ultrafast -vcodec libx265 -crf {crf} -c:a copy """{out}""" -y',
|
| 89 |
+
stdout=asyncio.subprocess.PIPE,
|
| 90 |
+
stderr=asyncio.subprocess.PIPE,
|
| 91 |
+
)
|
| 92 |
+
while proce.returncode != 0:
|
| 93 |
+
await asyncio.sleep(3)
|
| 94 |
+
with open(progress, "r+") as fil:
|
| 95 |
+
text = fil.read()
|
| 96 |
+
frames = re.findall("frame=(\\d+)", text)
|
| 97 |
+
size = re.findall("total_size=(\\d+)", text)
|
| 98 |
+
speed = 0
|
| 99 |
+
if len(frames):
|
| 100 |
+
elapse = int(frames[-1])
|
| 101 |
+
if len(size):
|
| 102 |
+
size = int(size[-1])
|
| 103 |
+
per = elapse * 100 / int(total_frames)
|
| 104 |
+
time_diff = time.time() - int(d_time)
|
| 105 |
+
speed = round(elapse / time_diff, 2)
|
| 106 |
+
if int(speed) != 0:
|
| 107 |
+
some_eta = ((int(total_frames) - elapse) / speed) * 1000
|
| 108 |
+
text = f"`Compressing {file_name} at {crf} CRF.\n`"
|
| 109 |
+
progress_str = "`[{0}{1}] {2}%\n\n`".format(
|
| 110 |
+
"".join("●" for _ in range(math.floor(per / 5))),
|
| 111 |
+
"".join("" for _ in range(20 - math.floor(per / 5))),
|
| 112 |
+
round(per, 2),
|
| 113 |
+
)
|
| 114 |
+
|
| 115 |
+
e_size = f"{humanbytes(size)} of ~{humanbytes((size / per) * 100)}"
|
| 116 |
+
eta = f"~{time_formatter(some_eta)}"
|
| 117 |
+
try:
|
| 118 |
+
await xxx.edit(
|
| 119 |
+
text
|
| 120 |
+
+ progress_str
|
| 121 |
+
+ "`"
|
| 122 |
+
+ e_size
|
| 123 |
+
+ "`"
|
| 124 |
+
+ "\n\n`"
|
| 125 |
+
+ eta
|
| 126 |
+
+ "`"
|
| 127 |
+
)
|
| 128 |
+
except MessageNotModifiedError:
|
| 129 |
+
pass
|
| 130 |
+
os.remove(file.name)
|
| 131 |
+
c_size = os.path.getsize(out)
|
| 132 |
+
f_time = time.time()
|
| 133 |
+
difff = time_formatter((f_time - d_time) * 1000)
|
| 134 |
+
await xxx.edit(
|
| 135 |
+
f"`Compressed {humanbytes(o_size)} to {humanbytes(c_size)} in {difff}\nTrying to Upload...`"
|
| 136 |
+
)
|
| 137 |
+
differ = 100 - ((c_size / o_size) * 100)
|
| 138 |
+
caption = f"**Original Size: **`{humanbytes(o_size)}`\n"
|
| 139 |
+
caption += f"**Compressed Size: **`{humanbytes(c_size)}`\n"
|
| 140 |
+
caption += f"**Compression Ratio: **`{differ:.2f}%`\n"
|
| 141 |
+
caption += f"\n**Time Taken To Compress: **`{difff}`"
|
| 142 |
+
n_file, _ = await e.client.fast_uploader(
|
| 143 |
+
out, show_progress=True, event=e, message="Uploading...", to_delete=True
|
| 144 |
+
)
|
| 145 |
+
if to_stream:
|
| 146 |
+
data = await metadata(out)
|
| 147 |
+
width = data["width"]
|
| 148 |
+
height = data["height"]
|
| 149 |
+
duration = data["duration"]
|
| 150 |
+
attributes = [
|
| 151 |
+
DocumentAttributeVideo(
|
| 152 |
+
duration=duration, w=width, h=height, supports_streaming=True
|
| 153 |
+
)
|
| 154 |
+
]
|
| 155 |
+
await e.client.send_file(
|
| 156 |
+
e.chat_id,
|
| 157 |
+
n_file,
|
| 158 |
+
thumb=ULTConfig.thumb,
|
| 159 |
+
caption=caption,
|
| 160 |
+
attributes=attributes,
|
| 161 |
+
force_document=False,
|
| 162 |
+
reply_to=e.reply_to_msg_id,
|
| 163 |
+
)
|
| 164 |
+
else:
|
| 165 |
+
await e.client.send_file(
|
| 166 |
+
e.chat_id,
|
| 167 |
+
n_file,
|
| 168 |
+
thumb=ULTConfig.thumb,
|
| 169 |
+
caption=caption,
|
| 170 |
+
force_document=True,
|
| 171 |
+
reply_to=e.reply_to_msg_id,
|
| 172 |
+
)
|
| 173 |
+
await xxx.delete()
|
| 174 |
+
os.remove(out)
|
| 175 |
+
os.remove(progress)
|
| 176 |
+
else:
|
| 177 |
+
await e.eor(get_string("audiotools_8"), time=5)
|
plugins/converter.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_converter")
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
import time
|
| 14 |
+
|
| 15 |
+
from . import LOGS
|
| 16 |
+
|
| 17 |
+
try:
|
| 18 |
+
import cv2
|
| 19 |
+
except ImportError:
|
| 20 |
+
cv2 = None
|
| 21 |
+
|
| 22 |
+
try:
|
| 23 |
+
from PIL import Image
|
| 24 |
+
except ImportError:
|
| 25 |
+
LOGS.info(f"{__file__}: PIL not Installed.")
|
| 26 |
+
Image = None
|
| 27 |
+
|
| 28 |
+
from . import upload_file as uf
|
| 29 |
+
|
| 30 |
+
from . import (
|
| 31 |
+
ULTConfig,
|
| 32 |
+
bash,
|
| 33 |
+
con,
|
| 34 |
+
downloader,
|
| 35 |
+
get_paste,
|
| 36 |
+
get_string,
|
| 37 |
+
udB,
|
| 38 |
+
ultroid_cmd,
|
| 39 |
+
uploader,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
opn = []
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
@ultroid_cmd(
|
| 46 |
+
pattern="thumbnail$",
|
| 47 |
+
)
|
| 48 |
+
async def _(e):
|
| 49 |
+
r = await e.get_reply_message()
|
| 50 |
+
if r.photo:
|
| 51 |
+
dl = await r.download_media()
|
| 52 |
+
elif r.document and r.document.thumbs:
|
| 53 |
+
dl = await r.download_media(thumb=-1)
|
| 54 |
+
else:
|
| 55 |
+
return await e.eor("`Reply to Photo or media with thumb...`")
|
| 56 |
+
nn = uf(dl)
|
| 57 |
+
os.remove(dl)
|
| 58 |
+
udB.set_key("CUSTOM_THUMBNAIL", str(nn))
|
| 59 |
+
await bash(f"wget {nn} -O resources/extras/ultroid.jpg")
|
| 60 |
+
await e.eor(get_string("cvt_6").format(nn), link_preview=False)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
@ultroid_cmd(
|
| 64 |
+
pattern="rename( (.*)|$)",
|
| 65 |
+
)
|
| 66 |
+
async def imak(event):
|
| 67 |
+
reply = await event.get_reply_message()
|
| 68 |
+
t = time.time()
|
| 69 |
+
if not reply:
|
| 70 |
+
return await event.eor(get_string("cvt_1"))
|
| 71 |
+
inp = event.pattern_match.group(1).strip()
|
| 72 |
+
if not inp:
|
| 73 |
+
return await event.eor(get_string("cvt_2"))
|
| 74 |
+
xx = await event.eor(get_string("com_1"))
|
| 75 |
+
if reply.media:
|
| 76 |
+
if hasattr(reply.media, "document"):
|
| 77 |
+
file = reply.media.document
|
| 78 |
+
image = await downloader(
|
| 79 |
+
reply.file.name or str(time.time()),
|
| 80 |
+
reply.media.document,
|
| 81 |
+
xx,
|
| 82 |
+
t,
|
| 83 |
+
get_string("com_5"),
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
file = image.name
|
| 87 |
+
else:
|
| 88 |
+
file = await event.client.download_media(reply.media)
|
| 89 |
+
if os.path.exists(inp):
|
| 90 |
+
os.remove(inp)
|
| 91 |
+
await bash(f'mv """{file}""" """{inp}"""')
|
| 92 |
+
if not os.path.exists(inp) or os.path.exists(inp) and not os.path.getsize(inp):
|
| 93 |
+
os.rename(file, inp)
|
| 94 |
+
k = time.time()
|
| 95 |
+
n_file, _ = await event.client.fast_uploader(
|
| 96 |
+
inp, show_progress=True, event=event, message="Uploading...", to_delete=True
|
| 97 |
+
)
|
| 98 |
+
await event.reply(
|
| 99 |
+
f"`{n_file.name}`",
|
| 100 |
+
file=n_file,
|
| 101 |
+
force_document=True,
|
| 102 |
+
thumb=ULTConfig.thumb,
|
| 103 |
+
)
|
| 104 |
+
os.remove(inp)
|
| 105 |
+
await xx.delete()
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
conv_keys = {
|
| 109 |
+
"img": "png",
|
| 110 |
+
"sticker": "webp",
|
| 111 |
+
"webp": "webp",
|
| 112 |
+
"image": "png",
|
| 113 |
+
"webm": "webm",
|
| 114 |
+
"gif": "gif",
|
| 115 |
+
"json": "json",
|
| 116 |
+
"tgs": "tgs",
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
@ultroid_cmd(
|
| 121 |
+
pattern="convert( (.*)|$)",
|
| 122 |
+
)
|
| 123 |
+
async def uconverter(event):
|
| 124 |
+
xx = await event.eor(get_string("com_1"))
|
| 125 |
+
a = await event.get_reply_message()
|
| 126 |
+
if a is None:
|
| 127 |
+
return await event.eor("`Reply to Photo or media with thumb...`")
|
| 128 |
+
input_ = event.pattern_match.group(1).strip()
|
| 129 |
+
b = await a.download_media("resources/downloads/")
|
| 130 |
+
if not b and (a.document and a.document.thumbs):
|
| 131 |
+
b = await a.download_media(thumb=-1)
|
| 132 |
+
if not b:
|
| 133 |
+
return await xx.edit(get_string("cvt_3"))
|
| 134 |
+
try:
|
| 135 |
+
convert = conv_keys[input_]
|
| 136 |
+
except KeyError:
|
| 137 |
+
return await xx.edit(get_string("sts_3").format("gif/img/sticker/webm"))
|
| 138 |
+
file = await con.convert(b, outname="ultroid", convert_to=convert)
|
| 139 |
+
print(file)
|
| 140 |
+
|
| 141 |
+
if file:
|
| 142 |
+
await event.client.send_file(
|
| 143 |
+
event.chat_id, file, reply_to=event.reply_to_msg_id or event.id
|
| 144 |
+
)
|
| 145 |
+
os.remove(file)
|
| 146 |
+
else:
|
| 147 |
+
await xx.edit("`Failed to convert`")
|
| 148 |
+
return
|
| 149 |
+
await xx.delete()
|
| 150 |
+
|
| 151 |
+
@ultroid_cmd(
|
| 152 |
+
pattern="doc( (.*)|$)",
|
| 153 |
+
)
|
| 154 |
+
async def _(event):
|
| 155 |
+
input_str = event.pattern_match.group(1).strip()
|
| 156 |
+
if not (input_str and event.is_reply):
|
| 157 |
+
return await event.eor(get_string("cvt_1"), time=5)
|
| 158 |
+
xx = await event.eor(get_string("com_1"))
|
| 159 |
+
a = await event.get_reply_message()
|
| 160 |
+
if not a.message:
|
| 161 |
+
return await xx.edit(get_string("ex_1"))
|
| 162 |
+
with open(input_str, "w") as b:
|
| 163 |
+
b.write(str(a.message))
|
| 164 |
+
await xx.edit(f"**Packing into** `{input_str}`")
|
| 165 |
+
await event.reply(file=input_str, thumb=ULTConfig.thumb)
|
| 166 |
+
await xx.delete()
|
| 167 |
+
os.remove(input_str)
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
@ultroid_cmd(
|
| 171 |
+
pattern="open( (.*)|$)",
|
| 172 |
+
)
|
| 173 |
+
async def _(event):
|
| 174 |
+
a = await event.get_reply_message()
|
| 175 |
+
b = event.pattern_match.group(1).strip()
|
| 176 |
+
if not ((a and a.media) or (b and os.path.exists(b))):
|
| 177 |
+
return await event.eor(get_string("cvt_7"), time=5)
|
| 178 |
+
xx = await event.eor(get_string("com_1"))
|
| 179 |
+
rem = None
|
| 180 |
+
if not b:
|
| 181 |
+
b = await a.download_media()
|
| 182 |
+
rem = True
|
| 183 |
+
try:
|
| 184 |
+
with open(b) as c:
|
| 185 |
+
d = c.read()
|
| 186 |
+
except UnicodeDecodeError:
|
| 187 |
+
return await xx.eor(get_string("cvt_8"), time=5)
|
| 188 |
+
try:
|
| 189 |
+
await xx.edit(f"```{d}```")
|
| 190 |
+
except BaseException:
|
| 191 |
+
what, data = await get_paste(d)
|
| 192 |
+
await xx.edit(
|
| 193 |
+
f"**MESSAGE EXCEEDS TELEGRAM LIMITS**\n\nSo Pasted It On [SPACEBIN]({data['link']})"
|
| 194 |
+
)
|
| 195 |
+
if rem:
|
| 196 |
+
os.remove(b)
|
plugins/core.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
from . import get_help
|
| 10 |
+
|
| 11 |
+
__doc__ = get_help("help_core")
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
import os
|
| 15 |
+
|
| 16 |
+
from pyUltroid.startup.loader import load_addons
|
| 17 |
+
|
| 18 |
+
from . import LOGS, async_searcher, eod, get_string, safeinstall, ultroid_cmd, un_plug
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
@ultroid_cmd(pattern="install", fullsudo=True)
|
| 22 |
+
async def install(event):
|
| 23 |
+
await safeinstall(event)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
@ultroid_cmd(
|
| 27 |
+
pattern=r"unload( (.*)|$)",
|
| 28 |
+
)
|
| 29 |
+
async def unload(event):
|
| 30 |
+
shortname = event.pattern_match.group(1).strip()
|
| 31 |
+
if not shortname:
|
| 32 |
+
await event.eor(get_string("core_9"))
|
| 33 |
+
return
|
| 34 |
+
lsd = os.listdir("addons")
|
| 35 |
+
zym = f"{shortname}.py"
|
| 36 |
+
if zym in lsd:
|
| 37 |
+
try:
|
| 38 |
+
un_plug(shortname)
|
| 39 |
+
await event.eor(f"**Uɴʟᴏᴀᴅᴇᴅ** `{shortname}` **Sᴜᴄᴄᴇssғᴜʟʟʏ.**", time=3)
|
| 40 |
+
except Exception as ex:
|
| 41 |
+
LOGS.exception(ex)
|
| 42 |
+
return await event.eor(str(ex))
|
| 43 |
+
elif zym in os.listdir("plugins"):
|
| 44 |
+
return await event.eor(get_string("core_11"), time=3)
|
| 45 |
+
else:
|
| 46 |
+
await event.eor(f"**Nᴏ Pʟᴜɢɪɴ Nᴀᴍᴇᴅ** `{shortname}`", time=3)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
@ultroid_cmd(
|
| 50 |
+
pattern=r"uninstall( (.*)|$)",
|
| 51 |
+
)
|
| 52 |
+
async def uninstall(event):
|
| 53 |
+
shortname = event.pattern_match.group(1).strip()
|
| 54 |
+
if not shortname:
|
| 55 |
+
await event.eor(get_string("core_13"))
|
| 56 |
+
return
|
| 57 |
+
lsd = os.listdir("addons")
|
| 58 |
+
zym = f"{shortname}.py"
|
| 59 |
+
if zym in lsd:
|
| 60 |
+
try:
|
| 61 |
+
un_plug(shortname)
|
| 62 |
+
await event.eor(f"**Uɴɪɴsᴛᴀʟʟᴇᴅ** `{shortname}` **Sᴜᴄᴄᴇssғᴜʟʟʏ.**", time=3)
|
| 63 |
+
os.remove(f"addons/{shortname}.py")
|
| 64 |
+
except Exception as ex:
|
| 65 |
+
return await event.eor(str(ex))
|
| 66 |
+
elif zym in os.listdir("plugins"):
|
| 67 |
+
return await event.eor(get_string("core_15"), time=3)
|
| 68 |
+
else:
|
| 69 |
+
return await event.eor(f"**Nᴏ Pʟᴜɢɪɴ Nᴀᴍᴇᴅ** `{shortname}`", time=3)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
@ultroid_cmd(
|
| 73 |
+
pattern=r"load( (.*)|$)",
|
| 74 |
+
fullsudo=True,
|
| 75 |
+
)
|
| 76 |
+
async def load(event):
|
| 77 |
+
shortname = event.pattern_match.group(1).strip()
|
| 78 |
+
if not shortname:
|
| 79 |
+
await event.eor(get_string("core_16"))
|
| 80 |
+
return
|
| 81 |
+
try:
|
| 82 |
+
try:
|
| 83 |
+
un_plug(shortname)
|
| 84 |
+
except BaseException:
|
| 85 |
+
pass
|
| 86 |
+
load_addons(f"addons/{shortname}.py")
|
| 87 |
+
await event.eor(get_string("core_17").format(shortname), time=3)
|
| 88 |
+
except Exception as e:
|
| 89 |
+
LOGS.exception(e)
|
| 90 |
+
await eod(
|
| 91 |
+
event,
|
| 92 |
+
get_string("core_18").format(shortname, e),
|
| 93 |
+
time=3,
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
@ultroid_cmd(pattern="getaddons( (.*)|$)", fullsudo=True)
|
| 98 |
+
async def get_the_addons_lol(event):
|
| 99 |
+
thelink = event.pattern_match.group(1).strip()
|
| 100 |
+
xx = await event.eor(get_string("com_1"))
|
| 101 |
+
fool = get_string("gas_1")
|
| 102 |
+
if thelink is None:
|
| 103 |
+
return await xx.eor(fool, time=10)
|
| 104 |
+
split_thelink = thelink.split("/")
|
| 105 |
+
if not ("raw" in thelink and thelink.endswith(".py")):
|
| 106 |
+
return await xx.eor(fool, time=10)
|
| 107 |
+
name_of_it = split_thelink[-1]
|
| 108 |
+
plug = await async_searcher(thelink)
|
| 109 |
+
fil = f"addons/{name_of_it}"
|
| 110 |
+
await xx.edit("Packing the codes...")
|
| 111 |
+
with open(fil, "w", encoding="utf-8") as uult:
|
| 112 |
+
uult.write(plug)
|
| 113 |
+
await xx.edit("Packed. Now loading the plugin..")
|
| 114 |
+
shortname = name_of_it.split(".")[0]
|
| 115 |
+
try:
|
| 116 |
+
load_addons(fil)
|
| 117 |
+
await xx.eor(get_string("core_17").format(shortname), time=15)
|
| 118 |
+
except Exception as e:
|
| 119 |
+
LOGS.exception(e)
|
| 120 |
+
await eod(
|
| 121 |
+
xx,
|
| 122 |
+
get_string("core_18").format(shortname, e),
|
| 123 |
+
time=3,
|
| 124 |
+
)
|
plugins/database.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
from . import get_help
|
| 10 |
+
|
| 11 |
+
__doc__ = get_help("help_database")
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
import re
|
| 15 |
+
|
| 16 |
+
from . import Redis, eor, get_string, udB, ultroid_cmd
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
@ultroid_cmd(pattern="setdb( (.*)|$)", fullsudo=True)
|
| 20 |
+
async def _(ult):
|
| 21 |
+
match = ult.pattern_match.group(1).strip()
|
| 22 |
+
if not match:
|
| 23 |
+
return await ult.eor("Provide key and value to set!")
|
| 24 |
+
try:
|
| 25 |
+
delim = " " if re.search("[|]", match) is None else " | "
|
| 26 |
+
data = match.split(delim, maxsplit=1)
|
| 27 |
+
if data[0] in ["--extend", "-e"]:
|
| 28 |
+
data = data[1].split(maxsplit=1)
|
| 29 |
+
data[1] = f"{str(udB.get_key(data[0]))} {data[1]}"
|
| 30 |
+
udB.set_key(data[0], data[1])
|
| 31 |
+
await ult.eor(
|
| 32 |
+
f"**DB Key Value Pair Updated\nKey :** `{data[0]}`\n**Value :** `{data[1]}`"
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
except BaseException:
|
| 36 |
+
await ult.eor(get_string("com_7"))
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
@ultroid_cmd(pattern="deldb( (.*)|$)", fullsudo=True)
|
| 40 |
+
async def _(ult):
|
| 41 |
+
key = ult.pattern_match.group(1).strip()
|
| 42 |
+
if not key:
|
| 43 |
+
return await ult.eor("Give me a key name to delete!", time=5)
|
| 44 |
+
_ = key.split(maxsplit=1)
|
| 45 |
+
try:
|
| 46 |
+
if _[0] == "-m":
|
| 47 |
+
for key in _[1].split():
|
| 48 |
+
k = udB.del_key(key)
|
| 49 |
+
key = _[1]
|
| 50 |
+
else:
|
| 51 |
+
k = udB.del_key(key)
|
| 52 |
+
if k == 0:
|
| 53 |
+
return await ult.eor("`No Such Key.`")
|
| 54 |
+
await ult.eor(f"`Successfully deleted key {key}`")
|
| 55 |
+
except BaseException:
|
| 56 |
+
await ult.eor(get_string("com_7"))
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
@ultroid_cmd(pattern="rendb( (.*)|$)", fullsudo=True)
|
| 60 |
+
async def _(ult):
|
| 61 |
+
match = ult.pattern_match.group(1).strip()
|
| 62 |
+
if not match:
|
| 63 |
+
return await ult.eor("`Provide Keys name to rename..`")
|
| 64 |
+
delim = " " if re.search("[|]", match) is None else " | "
|
| 65 |
+
data = match.split(delim)
|
| 66 |
+
if Redis(data[0]):
|
| 67 |
+
try:
|
| 68 |
+
udB.rename(data[0], data[1])
|
| 69 |
+
await eor(
|
| 70 |
+
ult,
|
| 71 |
+
f"**DB Key Rename Successful\nOld Key :** `{data[0]}`\n**New Key :** `{data[1]}`",
|
| 72 |
+
)
|
| 73 |
+
|
| 74 |
+
except BaseException:
|
| 75 |
+
await ult.eor(get_string("com_7"))
|
| 76 |
+
else:
|
| 77 |
+
await ult.eor("Key not found")
|
plugins/devtools.py
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_devtools")
|
| 11 |
+
|
| 12 |
+
import inspect
|
| 13 |
+
import sys
|
| 14 |
+
import traceback
|
| 15 |
+
from io import BytesIO, StringIO
|
| 16 |
+
from os import remove
|
| 17 |
+
from pprint import pprint
|
| 18 |
+
|
| 19 |
+
from telethon.utils import get_display_name
|
| 20 |
+
|
| 21 |
+
from pyUltroid import _ignore_eval
|
| 22 |
+
|
| 23 |
+
from . import *
|
| 24 |
+
|
| 25 |
+
# Used for Formatting Eval Code, if installed
|
| 26 |
+
try:
|
| 27 |
+
import black
|
| 28 |
+
except ImportError:
|
| 29 |
+
black = None
|
| 30 |
+
from random import choice
|
| 31 |
+
|
| 32 |
+
try:
|
| 33 |
+
from yaml import safe_load
|
| 34 |
+
except ImportError:
|
| 35 |
+
from pyUltroid.fns.tools import safe_load
|
| 36 |
+
|
| 37 |
+
from . import upload_file as uf
|
| 38 |
+
from telethon.tl import functions
|
| 39 |
+
|
| 40 |
+
fn = functions
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@ultroid_cmd(
|
| 44 |
+
pattern="sysinfo$",
|
| 45 |
+
)
|
| 46 |
+
async def _(e):
|
| 47 |
+
xx = await e.eor(get_string("com_1"))
|
| 48 |
+
x, y = await bash("neofetch|sed 's/\x1B\\[[0-9;\\?]*[a-zA-Z]//g' >> neo.txt")
|
| 49 |
+
if y and y.endswith("NOT_FOUND"):
|
| 50 |
+
return await xx.edit(f"Error: `{y}`")
|
| 51 |
+
with open("neo.txt", "r", encoding="utf-8") as neo:
|
| 52 |
+
p = (neo.read()).replace("\n\n", "")
|
| 53 |
+
haa = await Carbon(code=p, file_name="neofetch", backgroundColor=choice(ATRA_COL))
|
| 54 |
+
if isinstance(haa, dict):
|
| 55 |
+
await xx.edit(f"`{haa}`")
|
| 56 |
+
else:
|
| 57 |
+
await e.reply(file=haa)
|
| 58 |
+
await xx.delete()
|
| 59 |
+
remove("neo.txt")
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
@ultroid_cmd(pattern="bash", fullsudo=True, only_devs=True)
|
| 63 |
+
async def _(event):
|
| 64 |
+
carb, rayso, yamlf = None, None, False
|
| 65 |
+
try:
|
| 66 |
+
cmd = event.text.split(" ", maxsplit=1)[1]
|
| 67 |
+
if cmd.split()[0] in ["-c", "--carbon"]:
|
| 68 |
+
cmd = cmd.split(maxsplit=1)[1]
|
| 69 |
+
carb = True
|
| 70 |
+
if cmd.split()[0] in ["-r", "--rayso"]:
|
| 71 |
+
cmd = cmd.split(maxsplit=1)[1]
|
| 72 |
+
rayso = True
|
| 73 |
+
except IndexError:
|
| 74 |
+
return await event.eor(get_string("devs_1"), time=10)
|
| 75 |
+
xx = await event.eor(get_string("com_1"))
|
| 76 |
+
reply_to_id = event.reply_to_msg_id or event.id
|
| 77 |
+
stdout, stderr = await bash(cmd, run_code=1)
|
| 78 |
+
OUT = f"**☞ BASH\n\n• COMMAND:**\n`{cmd}` \n\n"
|
| 79 |
+
err, out = "", ""
|
| 80 |
+
if stderr:
|
| 81 |
+
err = f"**• ERROR:** \n`{stderr}`\n\n"
|
| 82 |
+
if stdout:
|
| 83 |
+
if (carb or udB.get_key("CARBON_ON_BASH")) and (
|
| 84 |
+
event.is_private
|
| 85 |
+
or event.chat.admin_rights
|
| 86 |
+
or event.chat.creator
|
| 87 |
+
or event.chat.default_banned_rights.embed_links
|
| 88 |
+
):
|
| 89 |
+
li = await Carbon(
|
| 90 |
+
code=stdout,
|
| 91 |
+
file_name="bash",
|
| 92 |
+
download=True,
|
| 93 |
+
backgroundColor=choice(ATRA_COL),
|
| 94 |
+
)
|
| 95 |
+
if isinstance(li, dict):
|
| 96 |
+
await xx.edit(
|
| 97 |
+
f"Unknown Response from Carbon: `{li}`\n\nstdout`:{stdout}`\nstderr: `{stderr}`"
|
| 98 |
+
)
|
| 99 |
+
return
|
| 100 |
+
url = uf(li)
|
| 101 |
+
OUT = f"[\xad]({url}){OUT}"
|
| 102 |
+
out = "**• OUTPUT:**"
|
| 103 |
+
remove(li)
|
| 104 |
+
elif (rayso or udB.get_key("RAYSO_ON_BASH")) and (
|
| 105 |
+
event.is_private
|
| 106 |
+
or event.chat.admin_rights
|
| 107 |
+
or event.chat.creator
|
| 108 |
+
or event.chat.default_banned_rights.embed_links
|
| 109 |
+
):
|
| 110 |
+
li = await Carbon(
|
| 111 |
+
code=stdout,
|
| 112 |
+
file_name="bash",
|
| 113 |
+
download=True,
|
| 114 |
+
backgroundColor=choice(ATRA_COL),
|
| 115 |
+
rayso=True,
|
| 116 |
+
)
|
| 117 |
+
if isinstance(li, dict):
|
| 118 |
+
await xx.edit(
|
| 119 |
+
f"Unknown Response from Carbon: `{li}`\n\nstdout`:{stdout}`\nstderr: `{stderr}`"
|
| 120 |
+
)
|
| 121 |
+
return
|
| 122 |
+
url = uf(li)
|
| 123 |
+
OUT = f"[\xad]({url}){OUT}"
|
| 124 |
+
out = "**• OUTPUT:**"
|
| 125 |
+
remove(li)
|
| 126 |
+
else:
|
| 127 |
+
if "pip" in cmd and all(":" in line for line in stdout.split("\n")):
|
| 128 |
+
try:
|
| 129 |
+
load = safe_load(stdout)
|
| 130 |
+
stdout = ""
|
| 131 |
+
for data in list(load.keys()):
|
| 132 |
+
res = load[data] or ""
|
| 133 |
+
if res and "http" not in str(res):
|
| 134 |
+
res = f"`{res}`"
|
| 135 |
+
stdout += f"**{data}** : {res}\n"
|
| 136 |
+
yamlf = True
|
| 137 |
+
except Exception as er:
|
| 138 |
+
stdout = f"`{stdout}`"
|
| 139 |
+
LOGS.exception(er)
|
| 140 |
+
else:
|
| 141 |
+
stdout = f"`{stdout}`"
|
| 142 |
+
out = f"**• OUTPUT:**\n{stdout}"
|
| 143 |
+
if not stderr and not stdout:
|
| 144 |
+
out = "**• OUTPUT:**\n`Success`"
|
| 145 |
+
OUT += err + out
|
| 146 |
+
if len(OUT) > 4096:
|
| 147 |
+
ultd = err + out
|
| 148 |
+
with BytesIO(str.encode(ultd)) as out_file:
|
| 149 |
+
out_file.name = "bash.txt"
|
| 150 |
+
await event.client.send_file(
|
| 151 |
+
event.chat_id,
|
| 152 |
+
out_file,
|
| 153 |
+
force_document=True,
|
| 154 |
+
thumb=ULTConfig.thumb,
|
| 155 |
+
allow_cache=False,
|
| 156 |
+
caption=f"`{cmd}`" if len(cmd) < 998 else None,
|
| 157 |
+
reply_to=reply_to_id,
|
| 158 |
+
)
|
| 159 |
+
|
| 160 |
+
await xx.delete()
|
| 161 |
+
else:
|
| 162 |
+
await xx.edit(OUT, link_preview=not yamlf)
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
pp = pprint # ignore: pylint
|
| 166 |
+
bot = ultroid = ultroid_bot
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
class u:
|
| 170 |
+
_ = ""
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
def _parse_eval(value=None):
|
| 174 |
+
if not value:
|
| 175 |
+
return value
|
| 176 |
+
if hasattr(value, "stringify"):
|
| 177 |
+
try:
|
| 178 |
+
return value.stringify()
|
| 179 |
+
except TypeError:
|
| 180 |
+
pass
|
| 181 |
+
elif isinstance(value, dict):
|
| 182 |
+
try:
|
| 183 |
+
return json_parser(value, indent=1)
|
| 184 |
+
except BaseException:
|
| 185 |
+
pass
|
| 186 |
+
elif isinstance(value, list):
|
| 187 |
+
newlist = "["
|
| 188 |
+
for index, child in enumerate(value):
|
| 189 |
+
newlist += "\n " + str(_parse_eval(child))
|
| 190 |
+
if index < len(value) - 1:
|
| 191 |
+
newlist += ","
|
| 192 |
+
newlist += "\n]"
|
| 193 |
+
return newlist
|
| 194 |
+
return str(value)
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
@ultroid_cmd(pattern="eval", fullsudo=True, only_devs=True)
|
| 198 |
+
async def _(event):
|
| 199 |
+
try:
|
| 200 |
+
cmd = event.text.split(maxsplit=1)[1]
|
| 201 |
+
except IndexError:
|
| 202 |
+
return await event.eor(get_string("devs_2"), time=5)
|
| 203 |
+
xx = None
|
| 204 |
+
mode = ""
|
| 205 |
+
spli = cmd.split()
|
| 206 |
+
|
| 207 |
+
async def get_():
|
| 208 |
+
try:
|
| 209 |
+
cm = cmd.split(maxsplit=1)[1]
|
| 210 |
+
except IndexError:
|
| 211 |
+
await event.eor("->> Wrong Format <<-")
|
| 212 |
+
cm = None
|
| 213 |
+
return cm
|
| 214 |
+
|
| 215 |
+
if spli[0] in ["-s", "--silent"]:
|
| 216 |
+
await event.delete()
|
| 217 |
+
mode = "silent"
|
| 218 |
+
elif spli[0] in ["-n", "-noedit"]:
|
| 219 |
+
mode = "no-edit"
|
| 220 |
+
xx = await event.reply(get_string("com_1"))
|
| 221 |
+
elif spli[0] in ["-gs", "--source"]:
|
| 222 |
+
mode = "gsource"
|
| 223 |
+
elif spli[0] in ["-ga", "--args"]:
|
| 224 |
+
mode = "g-args"
|
| 225 |
+
if mode:
|
| 226 |
+
cmd = await get_()
|
| 227 |
+
if not cmd:
|
| 228 |
+
return
|
| 229 |
+
if not mode == "silent" and not xx:
|
| 230 |
+
xx = await event.eor(get_string("com_1"))
|
| 231 |
+
if black:
|
| 232 |
+
try:
|
| 233 |
+
cmd = black.format_str(cmd, mode=black.Mode())
|
| 234 |
+
except BaseException:
|
| 235 |
+
# Consider it as Code Error, and move on to be shown ahead.
|
| 236 |
+
pass
|
| 237 |
+
reply_to_id = event.reply_to_msg_id or event
|
| 238 |
+
if any(item in cmd for item in KEEP_SAFE().All) and (
|
| 239 |
+
not (event.out or event.sender_id == ultroid_bot.uid)
|
| 240 |
+
):
|
| 241 |
+
warning = await event.forward_to(udB.get_key("LOG_CHANNEL"))
|
| 242 |
+
await warning.reply(
|
| 243 |
+
f"Malicious Activities suspected by {inline_mention(await event.get_sender())}"
|
| 244 |
+
)
|
| 245 |
+
_ignore_eval.append(event.sender_id)
|
| 246 |
+
return await xx.edit(
|
| 247 |
+
"`Malicious Activities suspected⚠️!\nReported to owner. Aborted this request!`"
|
| 248 |
+
)
|
| 249 |
+
old_stderr = sys.stderr
|
| 250 |
+
old_stdout = sys.stdout
|
| 251 |
+
redirected_output = sys.stdout = StringIO()
|
| 252 |
+
redirected_error = sys.stderr = StringIO()
|
| 253 |
+
stdout, stderr, exc, timeg = None, None, None, None
|
| 254 |
+
tima = time.time()
|
| 255 |
+
try:
|
| 256 |
+
value = await aexec(cmd, event)
|
| 257 |
+
except Exception:
|
| 258 |
+
value = None
|
| 259 |
+
exc = traceback.format_exc()
|
| 260 |
+
tima = time.time() - tima
|
| 261 |
+
stdout = redirected_output.getvalue()
|
| 262 |
+
stderr = redirected_error.getvalue()
|
| 263 |
+
sys.stdout = old_stdout
|
| 264 |
+
sys.stderr = old_stderr
|
| 265 |
+
if value:
|
| 266 |
+
try:
|
| 267 |
+
if mode == "gsource":
|
| 268 |
+
exc = inspect.getsource(value)
|
| 269 |
+
elif mode == "g-args":
|
| 270 |
+
args = inspect.signature(value).parameters.values()
|
| 271 |
+
name = ""
|
| 272 |
+
if hasattr(value, "__name__"):
|
| 273 |
+
name = value.__name__
|
| 274 |
+
exc = f"**{name}**\n\n" + "\n ".join([str(arg) for arg in args])
|
| 275 |
+
except Exception:
|
| 276 |
+
exc = traceback.format_exc()
|
| 277 |
+
evaluation = exc or stderr or stdout or _parse_eval(value) or get_string("instu_4")
|
| 278 |
+
if mode == "silent":
|
| 279 |
+
if exc:
|
| 280 |
+
msg = f"• <b>EVAL ERROR\n\n• CHAT:</b> <code>{get_display_name(event.chat)}</code> [<code>{event.chat_id}</code>]"
|
| 281 |
+
msg += f"\n\n∆ <b>CODE:</b>\n<code>{cmd}</code>\n\n∆ <b>ERROR:</b>\n<code>{exc}</code>"
|
| 282 |
+
log_chat = udB.get_key("LOG_CHANNEL")
|
| 283 |
+
if len(msg) > 4000:
|
| 284 |
+
with BytesIO(msg.encode()) as out_file:
|
| 285 |
+
out_file.name = "Eval-Error.txt"
|
| 286 |
+
return await event.client.send_message(
|
| 287 |
+
log_chat, f"`{cmd}`", file=out_file
|
| 288 |
+
)
|
| 289 |
+
await event.client.send_message(log_chat, msg, parse_mode="html")
|
| 290 |
+
return
|
| 291 |
+
tmt = tima * 1000
|
| 292 |
+
timef = time_formatter(tmt)
|
| 293 |
+
timeform = timef if not timef == "0s" else f"{tmt:.3f}ms"
|
| 294 |
+
final_output = "__►__ **EVAL** (__in {}__)\n```{}``` \n\n __►__ **OUTPUT**: \n```{}``` \n".format(
|
| 295 |
+
timeform,
|
| 296 |
+
cmd,
|
| 297 |
+
evaluation,
|
| 298 |
+
)
|
| 299 |
+
if len(final_output) > 4096:
|
| 300 |
+
final_output = evaluation
|
| 301 |
+
with BytesIO(str.encode(final_output)) as out_file:
|
| 302 |
+
out_file.name = "eval.txt"
|
| 303 |
+
await event.client.send_file(
|
| 304 |
+
event.chat_id,
|
| 305 |
+
out_file,
|
| 306 |
+
force_document=True,
|
| 307 |
+
thumb=ULTConfig.thumb,
|
| 308 |
+
allow_cache=False,
|
| 309 |
+
caption=f"```{cmd}```" if len(cmd) < 998 else None,
|
| 310 |
+
reply_to=reply_to_id,
|
| 311 |
+
)
|
| 312 |
+
return await xx.delete()
|
| 313 |
+
await xx.edit(final_output)
|
| 314 |
+
|
| 315 |
+
|
| 316 |
+
def _stringify(text=None, *args, **kwargs):
|
| 317 |
+
if text:
|
| 318 |
+
u._ = text
|
| 319 |
+
text = _parse_eval(text)
|
| 320 |
+
return print(text, *args, **kwargs)
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
async def aexec(code, event):
|
| 324 |
+
# Create a dedicated namespace for execution
|
| 325 |
+
exec_globals = {
|
| 326 |
+
'print': _stringify,
|
| 327 |
+
'p': _stringify,
|
| 328 |
+
'message': event,
|
| 329 |
+
'event': event,
|
| 330 |
+
'client': event.client,
|
| 331 |
+
'reply': await event.get_reply_message(),
|
| 332 |
+
'chat': event.chat_id,
|
| 333 |
+
'u': u,
|
| 334 |
+
'__builtins__': __builtins__,
|
| 335 |
+
'__name__': __name__
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
# Format the async function definition
|
| 339 |
+
wrapped_code = (
|
| 340 |
+
'async def __aexec(e, client):\n' +
|
| 341 |
+
'\n'.join(f' {line}' for line in code.split('\n'))
|
| 342 |
+
)
|
| 343 |
+
|
| 344 |
+
try:
|
| 345 |
+
# Execute the wrapped code in our custom namespace
|
| 346 |
+
exec(wrapped_code, exec_globals)
|
| 347 |
+
# Get the defined async function
|
| 348 |
+
func = exec_globals['__aexec']
|
| 349 |
+
# Execute it with proper parameters
|
| 350 |
+
return await func(event, event.client)
|
| 351 |
+
except Exception as e:
|
| 352 |
+
raise Exception(f"Failed to execute code: {str(e)}")
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
DUMMY_CPP = """#include <iostream>
|
| 356 |
+
using namespace std;
|
| 357 |
+
|
| 358 |
+
int main(){
|
| 359 |
+
!code
|
| 360 |
+
}
|
| 361 |
+
"""
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
@ultroid_cmd(pattern="cpp", only_devs=True)
|
| 365 |
+
async def doie(e):
|
| 366 |
+
match = e.text.split(" ", maxsplit=1)
|
| 367 |
+
try:
|
| 368 |
+
match = match[1]
|
| 369 |
+
except IndexError:
|
| 370 |
+
return await e.eor(get_string("devs_3"))
|
| 371 |
+
msg = await e.eor(get_string("com_1"))
|
| 372 |
+
if "main(" not in match:
|
| 373 |
+
new_m = "".join(" " * 4 + i + "\n" for i in match.split("\n"))
|
| 374 |
+
match = DUMMY_CPP.replace("!code", new_m)
|
| 375 |
+
open("cpp-ultroid.cpp", "w").write(match)
|
| 376 |
+
m = await bash("g++ -o CppUltroid cpp-ultroid.cpp")
|
| 377 |
+
o_cpp = f"• **Eval-Cpp**\n`{match}`"
|
| 378 |
+
if m[1]:
|
| 379 |
+
o_cpp += f"\n\n**• Error :**\n`{m[1]}`"
|
| 380 |
+
if len(o_cpp) > 3000:
|
| 381 |
+
os.remove("cpp-ultroid.cpp")
|
| 382 |
+
if os.path.exists("CppUltroid"):
|
| 383 |
+
os.remove("CppUltroid")
|
| 384 |
+
with BytesIO(str.encode(o_cpp)) as out_file:
|
| 385 |
+
out_file.name = "error.txt"
|
| 386 |
+
return await msg.reply(f"`{match}`", file=out_file)
|
| 387 |
+
return await eor(msg, o_cpp)
|
| 388 |
+
m = await bash("./CppUltroid")
|
| 389 |
+
if m[0] != "":
|
| 390 |
+
o_cpp += f"\n\n**• Output :**\n`{m[0]}`"
|
| 391 |
+
if m[1]:
|
| 392 |
+
o_cpp += f"\n\n**• Error :**\n`{m[1]}`"
|
| 393 |
+
if len(o_cpp) > 3000:
|
| 394 |
+
with BytesIO(str.encode(o_cpp)) as out_file:
|
| 395 |
+
out_file.name = "eval.txt"
|
| 396 |
+
await msg.reply(f"`{match}`", file=out_file)
|
| 397 |
+
else:
|
| 398 |
+
await eor(msg, o_cpp)
|
| 399 |
+
os.remove("CppUltroid")
|
| 400 |
+
os.remove("cpp-ultroid.cpp")
|
plugins/downloadupload.py
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_downloadupload")
|
| 11 |
+
|
| 12 |
+
import asyncio
|
| 13 |
+
import glob
|
| 14 |
+
import os
|
| 15 |
+
import time
|
| 16 |
+
from datetime import datetime as dt
|
| 17 |
+
|
| 18 |
+
from aiohttp.client_exceptions import InvalidURL
|
| 19 |
+
from telethon.errors.rpcerrorlist import MessageNotModifiedError
|
| 20 |
+
|
| 21 |
+
from pyUltroid.fns.helper import time_formatter
|
| 22 |
+
from pyUltroid.fns.tools import get_chat_and_msgid, set_attributes
|
| 23 |
+
|
| 24 |
+
from . import (
|
| 25 |
+
LOGS,
|
| 26 |
+
ULTConfig,
|
| 27 |
+
downloader,
|
| 28 |
+
eor,
|
| 29 |
+
fast_download,
|
| 30 |
+
get_all_files,
|
| 31 |
+
get_string,
|
| 32 |
+
progress,
|
| 33 |
+
time_formatter,
|
| 34 |
+
ultroid_cmd,
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@ultroid_cmd(
|
| 39 |
+
pattern="download( (.*)|$)",
|
| 40 |
+
)
|
| 41 |
+
async def down(event):
|
| 42 |
+
matched = event.pattern_match.group(1).strip()
|
| 43 |
+
msg = await event.eor(get_string("udl_4"))
|
| 44 |
+
if not matched:
|
| 45 |
+
return await eor(msg, get_string("udl_5"), time=5)
|
| 46 |
+
try:
|
| 47 |
+
splited = matched.split(" | ")
|
| 48 |
+
link = splited[0]
|
| 49 |
+
filename = splited[1]
|
| 50 |
+
except IndexError:
|
| 51 |
+
filename = None
|
| 52 |
+
s_time = time.time()
|
| 53 |
+
try:
|
| 54 |
+
filename, d = await fast_download(
|
| 55 |
+
link,
|
| 56 |
+
filename,
|
| 57 |
+
progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
|
| 58 |
+
progress(
|
| 59 |
+
d,
|
| 60 |
+
t,
|
| 61 |
+
msg,
|
| 62 |
+
s_time,
|
| 63 |
+
f"Downloading from {link}",
|
| 64 |
+
)
|
| 65 |
+
),
|
| 66 |
+
)
|
| 67 |
+
except InvalidURL:
|
| 68 |
+
return await msg.eor("`Invalid URL provided :(`", time=5)
|
| 69 |
+
await msg.eor(f"`{filename}` `downloaded in {time_formatter(d*1000)}.`")
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
@ultroid_cmd(
|
| 73 |
+
pattern="dl( (.*)|$)",
|
| 74 |
+
)
|
| 75 |
+
async def download(event):
|
| 76 |
+
match = event.pattern_match.group(1).strip()
|
| 77 |
+
if match and "t.me/" in match:
|
| 78 |
+
chat, msg = get_chat_and_msgid(match)
|
| 79 |
+
if not (chat and msg):
|
| 80 |
+
return await event.eor(get_string("gms_1"))
|
| 81 |
+
match = ""
|
| 82 |
+
ok = await event.client.get_messages(chat, ids=msg)
|
| 83 |
+
elif event.reply_to_msg_id:
|
| 84 |
+
ok = await event.get_reply_message()
|
| 85 |
+
else:
|
| 86 |
+
return await event.eor(get_string("cvt_3"), time=8)
|
| 87 |
+
xx = await event.eor(get_string("com_1"))
|
| 88 |
+
if not (ok and ok.media):
|
| 89 |
+
return await xx.eor(get_string("udl_1"), time=5)
|
| 90 |
+
s = dt.now()
|
| 91 |
+
k = time.time()
|
| 92 |
+
if hasattr(ok.media, "document"):
|
| 93 |
+
file = ok.media.document
|
| 94 |
+
mime_type = file.mime_type
|
| 95 |
+
filename = match or ok.file.name
|
| 96 |
+
if not filename:
|
| 97 |
+
if "audio" in mime_type:
|
| 98 |
+
filename = "audio_" + dt.now().isoformat("_", "seconds") + ".ogg"
|
| 99 |
+
elif "video" in mime_type:
|
| 100 |
+
filename = "video_" + dt.now().isoformat("_", "seconds") + ".mp4"
|
| 101 |
+
try:
|
| 102 |
+
result = await downloader(
|
| 103 |
+
f"resources/downloads/{filename}",
|
| 104 |
+
file,
|
| 105 |
+
xx,
|
| 106 |
+
k,
|
| 107 |
+
f"Downloading {filename}...",
|
| 108 |
+
)
|
| 109 |
+
|
| 110 |
+
except MessageNotModifiedError as err:
|
| 111 |
+
return await xx.edit(str(err))
|
| 112 |
+
file_name = result.name
|
| 113 |
+
else:
|
| 114 |
+
d = "resources/downloads/"
|
| 115 |
+
file_name = await event.client.download_media(
|
| 116 |
+
ok,
|
| 117 |
+
d,
|
| 118 |
+
progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
|
| 119 |
+
progress(
|
| 120 |
+
d,
|
| 121 |
+
t,
|
| 122 |
+
xx,
|
| 123 |
+
k,
|
| 124 |
+
get_string("com_5"),
|
| 125 |
+
),
|
| 126 |
+
),
|
| 127 |
+
)
|
| 128 |
+
e = dt.now()
|
| 129 |
+
t = time_formatter(((e - s).seconds) * 1000)
|
| 130 |
+
await xx.eor(get_string("udl_2").format(file_name, t))
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
@ultroid_cmd(
|
| 134 |
+
pattern="ul( (.*)|$)",
|
| 135 |
+
)
|
| 136 |
+
async def _(event):
|
| 137 |
+
msg = await event.eor(get_string("com_1"))
|
| 138 |
+
match = event.pattern_match.group(1)
|
| 139 |
+
if match:
|
| 140 |
+
match = match.strip()
|
| 141 |
+
if not event.out and match == ".env":
|
| 142 |
+
return await event.reply("`You can't do this...`")
|
| 143 |
+
stream, force_doc, delete, thumb = (
|
| 144 |
+
False,
|
| 145 |
+
True,
|
| 146 |
+
False,
|
| 147 |
+
ULTConfig.thumb,
|
| 148 |
+
)
|
| 149 |
+
if "--stream" in match:
|
| 150 |
+
stream = True
|
| 151 |
+
force_doc = False
|
| 152 |
+
if "--delete" in match:
|
| 153 |
+
delete = True
|
| 154 |
+
if "--no-thumb" in match:
|
| 155 |
+
thumb = None
|
| 156 |
+
arguments = ["--stream", "--delete", "--no-thumb"]
|
| 157 |
+
if any(item in match for item in arguments):
|
| 158 |
+
match = (
|
| 159 |
+
match.replace("--stream", "")
|
| 160 |
+
.replace("--delete", "")
|
| 161 |
+
.replace("--no-thumb", "")
|
| 162 |
+
.strip()
|
| 163 |
+
)
|
| 164 |
+
if match.endswith("/"):
|
| 165 |
+
match += "*"
|
| 166 |
+
results = glob.glob(match)
|
| 167 |
+
if not results and os.path.exists(match):
|
| 168 |
+
results = [match]
|
| 169 |
+
if not results:
|
| 170 |
+
try:
|
| 171 |
+
await event.reply(file=match)
|
| 172 |
+
return await event.try_delete()
|
| 173 |
+
except Exception as er:
|
| 174 |
+
LOGS.exception(er)
|
| 175 |
+
return await msg.eor(get_string("ls1"))
|
| 176 |
+
for result in results:
|
| 177 |
+
if os.path.isdir(result):
|
| 178 |
+
c, s = 0, 0
|
| 179 |
+
for files in get_all_files(result):
|
| 180 |
+
attributes = None
|
| 181 |
+
if stream:
|
| 182 |
+
try:
|
| 183 |
+
attributes = await set_attributes(files)
|
| 184 |
+
except KeyError as er:
|
| 185 |
+
LOGS.exception(er)
|
| 186 |
+
try:
|
| 187 |
+
file, _ = await event.client.fast_uploader(
|
| 188 |
+
files, show_progress=True, event=msg, to_delete=delete
|
| 189 |
+
)
|
| 190 |
+
await event.client.send_file(
|
| 191 |
+
event.chat_id,
|
| 192 |
+
file,
|
| 193 |
+
supports_streaming=stream,
|
| 194 |
+
force_document=force_doc,
|
| 195 |
+
thumb=thumb,
|
| 196 |
+
attributes=attributes,
|
| 197 |
+
caption=f"`Uploaded` `{files}` `in {time_formatter(_*1000)}`",
|
| 198 |
+
reply_to=event.reply_to_msg_id or event,
|
| 199 |
+
)
|
| 200 |
+
s += 1
|
| 201 |
+
except (ValueError, IsADirectoryError):
|
| 202 |
+
c += 1
|
| 203 |
+
break
|
| 204 |
+
attributes = None
|
| 205 |
+
if stream:
|
| 206 |
+
try:
|
| 207 |
+
attributes = await set_attributes(result)
|
| 208 |
+
except KeyError as er:
|
| 209 |
+
LOGS.exception(er)
|
| 210 |
+
file, _ = await event.client.fast_uploader(
|
| 211 |
+
result, show_progress=True, event=msg, to_delete=delete
|
| 212 |
+
)
|
| 213 |
+
await event.client.send_file(
|
| 214 |
+
event.chat_id,
|
| 215 |
+
file,
|
| 216 |
+
supports_streaming=stream,
|
| 217 |
+
force_document=force_doc,
|
| 218 |
+
thumb=thumb,
|
| 219 |
+
attributes=attributes,
|
| 220 |
+
caption=f"`Uploaded` `{result}` `in {time_formatter(_*1000)}`",
|
| 221 |
+
)
|
| 222 |
+
await msg.try_delete()
|
plugins/echo.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_echo")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
from telethon.utils import get_display_name
|
| 14 |
+
|
| 15 |
+
from pyUltroid.dB.echo_db import add_echo, check_echo, list_echo, rem_echo
|
| 16 |
+
|
| 17 |
+
from . import inline_mention, ultroid_cmd
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
@ultroid_cmd(pattern="addecho( (.*)|$)")
|
| 21 |
+
async def echo(e):
|
| 22 |
+
r = await e.get_reply_message()
|
| 23 |
+
if r:
|
| 24 |
+
user = r.sender_id
|
| 25 |
+
else:
|
| 26 |
+
try:
|
| 27 |
+
user = e.text.split()[1]
|
| 28 |
+
if user.startswith("@"):
|
| 29 |
+
ok = await e.client.get_entity(user)
|
| 30 |
+
user = ok.id
|
| 31 |
+
else:
|
| 32 |
+
user = int(user)
|
| 33 |
+
except BaseException:
|
| 34 |
+
return await e.eor("Reply To A user.", time=5)
|
| 35 |
+
if check_echo(e.chat_id, user):
|
| 36 |
+
return await e.eor("Echo already activated for this user.", time=5)
|
| 37 |
+
add_echo(e.chat_id, user)
|
| 38 |
+
ok = await e.client.get_entity(user)
|
| 39 |
+
user = inline_mention(ok)
|
| 40 |
+
await e.eor(f"Activated Echo For {user}.")
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@ultroid_cmd(pattern="remecho( (.*)|$)")
|
| 44 |
+
async def rm(e):
|
| 45 |
+
r = await e.get_reply_message()
|
| 46 |
+
if r:
|
| 47 |
+
user = r.sender_id
|
| 48 |
+
else:
|
| 49 |
+
try:
|
| 50 |
+
user = e.text.split()[1]
|
| 51 |
+
if user.startswith("@"):
|
| 52 |
+
ok = await e.client.get_entity(user)
|
| 53 |
+
user = ok.id
|
| 54 |
+
else:
|
| 55 |
+
user = int(user)
|
| 56 |
+
except BaseException:
|
| 57 |
+
return await e.eor("Reply To A User.", time=5)
|
| 58 |
+
if check_echo(e.chat_id, user):
|
| 59 |
+
rem_echo(e.chat_id, user)
|
| 60 |
+
ok = await e.client.get_entity(user)
|
| 61 |
+
user = f"[{get_display_name(ok)}](tg://user?id={ok.id})"
|
| 62 |
+
return await e.eor(f"Deactivated Echo For {user}.")
|
| 63 |
+
await e.eor("Echo not activated for this user")
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
@ultroid_cmd(pattern="listecho$")
|
| 67 |
+
async def lstecho(e):
|
| 68 |
+
if k := list_echo(e.chat_id):
|
| 69 |
+
user = "**Activated Echo For Users:**\n\n"
|
| 70 |
+
for x in k:
|
| 71 |
+
ok = await e.client.get_entity(int(x))
|
| 72 |
+
kk = f"[{get_display_name(ok)}](tg://user?id={ok.id})"
|
| 73 |
+
user += f"•{kk}" + "\n"
|
| 74 |
+
await e.eor(user)
|
| 75 |
+
else:
|
| 76 |
+
await e.eor("`List is Empty, For echo`", time=5)
|
plugins/extra.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("extra")
|
| 11 |
+
|
| 12 |
+
import asyncio
|
| 13 |
+
|
| 14 |
+
from . import get_string, ultroid_cmd
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
@ultroid_cmd(
|
| 18 |
+
pattern="del$",
|
| 19 |
+
manager=True,
|
| 20 |
+
)
|
| 21 |
+
async def delete_it(delme):
|
| 22 |
+
msg_src = await delme.get_reply_message()
|
| 23 |
+
if not msg_src:
|
| 24 |
+
return
|
| 25 |
+
await msg_src.try_delete()
|
| 26 |
+
await delme.try_delete()
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
@ultroid_cmd(
|
| 30 |
+
pattern="copy$",
|
| 31 |
+
)
|
| 32 |
+
async def copy(e):
|
| 33 |
+
reply = await e.get_reply_message()
|
| 34 |
+
if reply:
|
| 35 |
+
await reply.reply(reply)
|
| 36 |
+
return await e.try_delete()
|
| 37 |
+
await e.eor(get_string("ex_1"), time=5)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
@ultroid_cmd(
|
| 41 |
+
pattern="edit",
|
| 42 |
+
)
|
| 43 |
+
async def editer(edit):
|
| 44 |
+
message = edit.text
|
| 45 |
+
chat = await edit.get_input_chat()
|
| 46 |
+
string = str(message[6:])
|
| 47 |
+
reply = await edit.get_reply_message()
|
| 48 |
+
if reply and reply.text:
|
| 49 |
+
try:
|
| 50 |
+
await reply.edit(string)
|
| 51 |
+
await edit.delete()
|
| 52 |
+
except BaseException:
|
| 53 |
+
pass
|
| 54 |
+
else:
|
| 55 |
+
i = 1
|
| 56 |
+
async for message in edit.client.iter_messages(chat, from_user="me", limit=2):
|
| 57 |
+
if i == 2:
|
| 58 |
+
await message.edit(string)
|
| 59 |
+
await edit.delete()
|
| 60 |
+
break
|
| 61 |
+
i += 1
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
@ultroid_cmd(
|
| 65 |
+
pattern="reply$",
|
| 66 |
+
)
|
| 67 |
+
async def _(e):
|
| 68 |
+
if e.reply_to_msg_id:
|
| 69 |
+
chat = e.chat_id
|
| 70 |
+
try:
|
| 71 |
+
msg = (await e.client.get_messages(e.chat_id, limit=1, max_id=e.id))[0]
|
| 72 |
+
except IndexError:
|
| 73 |
+
return await e.eor(
|
| 74 |
+
"`You have previously sent no message to reply again...`", time=5
|
| 75 |
+
)
|
| 76 |
+
except BaseException as er:
|
| 77 |
+
return await e.eor(f"**ERROR:** `{er}`")
|
| 78 |
+
await asyncio.wait(
|
| 79 |
+
[
|
| 80 |
+
e.client.delete_messages(chat, [e.id, msg.id]),
|
| 81 |
+
e.client.send_message(chat, msg, reply_to=e.reply_to_msg_id),
|
| 82 |
+
]
|
| 83 |
+
)
|
| 84 |
+
else:
|
| 85 |
+
await e.try_delete()
|
plugins/fakeaction.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_fakeaction")
|
| 11 |
+
|
| 12 |
+
import math
|
| 13 |
+
import time
|
| 14 |
+
|
| 15 |
+
from pyUltroid.fns.admins import ban_time
|
| 16 |
+
|
| 17 |
+
from . import asyncio, get_string, ultroid_cmd
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
@ultroid_cmd(
|
| 21 |
+
pattern="f(typing|audio|contact|document|game|location|sticker|photo|round|video)( (.*)|$)"
|
| 22 |
+
)
|
| 23 |
+
async def _(e):
|
| 24 |
+
act = e.pattern_match.group(1).strip()
|
| 25 |
+
t = e.pattern_match.group(2)
|
| 26 |
+
if act in ["audio", "round", "video"]:
|
| 27 |
+
act = f"record-{act}"
|
| 28 |
+
if t.isdigit():
|
| 29 |
+
t = int(t)
|
| 30 |
+
elif t.endswith(("s", "h", "d", "m")):
|
| 31 |
+
t = math.ceil((ban_time(t)) - time.time())
|
| 32 |
+
else:
|
| 33 |
+
t = 60
|
| 34 |
+
await e.eor(get_string("fka_1").format(str(t)), time=5)
|
| 35 |
+
async with e.client.action(e.chat_id, act):
|
| 36 |
+
await asyncio.sleep(t)
|
plugins/fileshare.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_fileshare")
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
from pyUltroid.dB.filestore_db import del_stored, get_stored_msg, list_all_stored_msgs
|
| 15 |
+
from pyUltroid.fns.tools import get_file_link
|
| 16 |
+
|
| 17 |
+
from . import HNDLR, asst, get_string, in_pattern, udB, ultroid_bot, ultroid_cmd
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
@ultroid_cmd(pattern="store$")
|
| 21 |
+
async def filestoreplg(event):
|
| 22 |
+
msg = await event.get_reply_message()
|
| 23 |
+
if not msg:
|
| 24 |
+
return await event.eor(get_string("fsh_3"), time=10)
|
| 25 |
+
# allow storing both messages and media.
|
| 26 |
+
filehash = await get_file_link(msg)
|
| 27 |
+
link_to_file = f"https://t.me/{asst.me.username}?start={filehash}"
|
| 28 |
+
await event.eor(
|
| 29 |
+
get_string("fsh_2").format(link_to_file),
|
| 30 |
+
link_preview=False,
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
@ultroid_cmd("delstored ?(.*)")
|
| 35 |
+
async def _(event):
|
| 36 |
+
match = event.pattern_match.group(1)
|
| 37 |
+
if not match:
|
| 38 |
+
return await event.eor("`Give stored film's link to delete.`", time=5)
|
| 39 |
+
match = match.split("?start=")
|
| 40 |
+
botusername = match[0].split("/")[-1]
|
| 41 |
+
if botusername != asst.me.username:
|
| 42 |
+
return await event.eor(
|
| 43 |
+
"`Message/Media of provided link was not stored by this bot.`", time=5
|
| 44 |
+
)
|
| 45 |
+
msg_id = get_stored_msg(match[1])
|
| 46 |
+
if not msg_id:
|
| 47 |
+
return await event.eor(
|
| 48 |
+
"`Message/Media of provided link was already deleted.`", time=5
|
| 49 |
+
)
|
| 50 |
+
del_stored(match[1])
|
| 51 |
+
await ultroid_bot.delete_messages(udB.get_key("LOG_CHANNEL"), int(msg_id))
|
| 52 |
+
await event.eor("__Deleted__")
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
@ultroid_cmd("liststored$")
|
| 56 |
+
async def liststored(event):
|
| 57 |
+
files = list_all_stored_msgs()
|
| 58 |
+
if not files:
|
| 59 |
+
return await event.eor(get_string("fsh_4"), time=5)
|
| 60 |
+
msg = "**Stored files:**\n"
|
| 61 |
+
for c, i in enumerate(files, start=1):
|
| 62 |
+
msg += f"`{c}`. https://t.me/{asst.me.username}?start={i}\n"
|
| 63 |
+
if len(msg) > 4095:
|
| 64 |
+
with open("liststored.txt", "w") as f:
|
| 65 |
+
f.write(msg.replace("**", "").replace("`", ""))
|
| 66 |
+
await event.reply(get_string("fsh_1"), file="liststored.txt")
|
| 67 |
+
os.remove("liststored.txt")
|
| 68 |
+
return
|
| 69 |
+
await event.eor(msg, link_preview=False)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
@in_pattern("filestore", owner=True)
|
| 73 |
+
async def file_short(event):
|
| 74 |
+
all_ = list_all_stored_msgs()
|
| 75 |
+
res = []
|
| 76 |
+
if all_:
|
| 77 |
+
LOG_CHA = udB.get_key("LOG_CHANNEL")
|
| 78 |
+
for msg in all_[:50]:
|
| 79 |
+
m_id = get_stored_msg(msg)
|
| 80 |
+
if not m_id:
|
| 81 |
+
continue
|
| 82 |
+
message = await asst.get_messages(LOG_CHA, ids=m_id)
|
| 83 |
+
if not message:
|
| 84 |
+
continue
|
| 85 |
+
if message.media:
|
| 86 |
+
res.append(await event.builder.document(title=msg, file=message.media))
|
| 87 |
+
elif message.text:
|
| 88 |
+
res.append(
|
| 89 |
+
await event.builder.article(title=message.text, text=message.text)
|
| 90 |
+
)
|
| 91 |
+
if not res:
|
| 92 |
+
title = "You have no stored file :("
|
| 93 |
+
text = f"{title}\n\nRead `{HNDLR}help fileshare` to know how to store."
|
| 94 |
+
return await event.answer([await event.builder.article(title=title, text=text)])
|
| 95 |
+
await event.answer(res, switch_pm="• File Store •", switch_pm_param="start")
|
plugins/filter.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_filter")
|
| 11 |
+
|
| 12 |
+
import os
|
| 13 |
+
import re
|
| 14 |
+
|
| 15 |
+
from telethon.tl.types import User
|
| 16 |
+
from telethon.utils import pack_bot_file_id
|
| 17 |
+
|
| 18 |
+
from pyUltroid.dB.filter_db import add_filter, get_filter, list_filter, rem_filter
|
| 19 |
+
from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button
|
| 20 |
+
|
| 21 |
+
from . import events, get_string, mediainfo, udB, ultroid_bot, ultroid_cmd, upload_file
|
| 22 |
+
from ._inline import something
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@ultroid_cmd(pattern="addfilter( (.*)|$)")
|
| 26 |
+
async def af(e):
|
| 27 |
+
wrd = (e.pattern_match.group(1).strip()).lower()
|
| 28 |
+
wt = await e.get_reply_message()
|
| 29 |
+
chat = e.chat_id
|
| 30 |
+
if not (wt and wrd):
|
| 31 |
+
return await e.eor(get_string("flr_1"))
|
| 32 |
+
btn = format_btn(wt.buttons) if wt.buttons else None
|
| 33 |
+
if wt and wt.media:
|
| 34 |
+
wut = mediainfo(wt.media)
|
| 35 |
+
if wut.startswith(("pic", "gif")):
|
| 36 |
+
dl = await wt.download_media()
|
| 37 |
+
m = upload_file(dl)
|
| 38 |
+
os.remove(dl)
|
| 39 |
+
elif wut == "video":
|
| 40 |
+
if wt.media.document.size > 8 * 1000 * 1000:
|
| 41 |
+
return await e.eor(get_string("com_4"), time=5)
|
| 42 |
+
dl = await wt.download_media()
|
| 43 |
+
m = upload_file(dl)
|
| 44 |
+
os.remove(dl)
|
| 45 |
+
else:
|
| 46 |
+
m = pack_bot_file_id(wt.media)
|
| 47 |
+
if wt.text:
|
| 48 |
+
txt = wt.text
|
| 49 |
+
if not btn:
|
| 50 |
+
txt, btn = get_msg_button(wt.text)
|
| 51 |
+
add_filter(chat, wrd, txt, m, btn)
|
| 52 |
+
else:
|
| 53 |
+
add_filter(chat, wrd, None, m, btn)
|
| 54 |
+
else:
|
| 55 |
+
txt = wt.text
|
| 56 |
+
if not btn:
|
| 57 |
+
txt, btn = get_msg_button(wt.text)
|
| 58 |
+
add_filter(chat, wrd, txt, None, btn)
|
| 59 |
+
await e.eor(get_string("flr_4").format(wrd))
|
| 60 |
+
ultroid_bot.add_handler(filter_func, events.NewMessage())
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
@ultroid_cmd(pattern="remfilter( (.*)|$)")
|
| 64 |
+
async def rf(e):
|
| 65 |
+
wrd = (e.pattern_match.group(1).strip()).lower()
|
| 66 |
+
chat = e.chat_id
|
| 67 |
+
if not wrd:
|
| 68 |
+
return await e.eor(get_string("flr_3"))
|
| 69 |
+
rem_filter(int(chat), wrd)
|
| 70 |
+
await e.eor(get_string("flr_5").format(wrd))
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
@ultroid_cmd(pattern="listfilter$")
|
| 74 |
+
async def lsnote(e):
|
| 75 |
+
if x := list_filter(e.chat_id):
|
| 76 |
+
sd = "Filters Found In This Chats Are\n\n"
|
| 77 |
+
return await e.eor(sd + x)
|
| 78 |
+
await e.eor(get_string("flr_6"))
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
async def filter_func(e):
|
| 82 |
+
if isinstance(e.sender, User) and e.sender.bot:
|
| 83 |
+
return
|
| 84 |
+
xx = (e.text).lower()
|
| 85 |
+
chat = e.chat_id
|
| 86 |
+
if x := get_filter(chat):
|
| 87 |
+
for c in x:
|
| 88 |
+
pat = r"( |^|[^\w])" + re.escape(c) + r"( |$|[^\w])"
|
| 89 |
+
if re.search(pat, xx):
|
| 90 |
+
if k := x.get(c):
|
| 91 |
+
msg = k["msg"]
|
| 92 |
+
media = k["media"]
|
| 93 |
+
if k.get("button"):
|
| 94 |
+
btn = create_tl_btn(k["button"])
|
| 95 |
+
return await something(e, msg, media, btn)
|
| 96 |
+
await e.reply(msg, file=media)
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
if udB.get_key("FILTERS"):
|
| 100 |
+
ultroid_bot.add_handler(filter_func, events.NewMessage())
|
plugins/fontgen.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
|
| 8 |
+
from . import get_help
|
| 9 |
+
|
| 10 |
+
__doc__ = get_help("help_fontgen")
|
| 11 |
+
|
| 12 |
+
import string
|
| 13 |
+
|
| 14 |
+
from . import eod, ultroid_cmd
|
| 15 |
+
|
| 16 |
+
_default = string.ascii_letters
|
| 17 |
+
Fonts = {
|
| 18 |
+
"small caps": "ᴀʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘϙʀsᴛᴜᴠᴡxʏᴢABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
| 19 |
+
"monospace": "𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉",
|
| 20 |
+
"double stroke": "𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ",
|
| 21 |
+
"script royal": "𝒶𝒷𝒸𝒹𝑒𝒻𝑔𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝑜𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏𝒜ℬ𝒞𝒟ℰℱ𝒢ℋℐ𝒥𝒦ℒℳ𝒩𝒪𝒫𝒬ℛ𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵",
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@ultroid_cmd(
|
| 26 |
+
pattern="font( (.*)|$)",
|
| 27 |
+
)
|
| 28 |
+
async def _(e):
|
| 29 |
+
input = e.pattern_match.group(1).strip()
|
| 30 |
+
reply = await e.get_reply_message()
|
| 31 |
+
if not input:
|
| 32 |
+
m = "**Available Fonts**\n\n"
|
| 33 |
+
for x in Fonts.keys():
|
| 34 |
+
m += f"• `{x}`\n"
|
| 35 |
+
return await e.eor(m, time=5)
|
| 36 |
+
if not reply:
|
| 37 |
+
try:
|
| 38 |
+
_ = input.split(":", maxsplit=1)
|
| 39 |
+
font = _[0][:-1]
|
| 40 |
+
text = _[1]
|
| 41 |
+
except IndexError:
|
| 42 |
+
return await eod(e, help)
|
| 43 |
+
elif not input:
|
| 44 |
+
return await eod(e, "`Give font dude :/`")
|
| 45 |
+
else:
|
| 46 |
+
font = input
|
| 47 |
+
text = reply.message
|
| 48 |
+
if font not in Fonts.keys():
|
| 49 |
+
return await e.eor(f"`{font} not in font list`.", time=5)
|
| 50 |
+
msg = gen_font(text, Fonts[font])
|
| 51 |
+
await e.eor(msg)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def gen_font(text, new_font):
|
| 55 |
+
new_font = " ".join(new_font).split()
|
| 56 |
+
for q in text:
|
| 57 |
+
if q in _default:
|
| 58 |
+
new = new_font[_default.index(q)]
|
| 59 |
+
text = text.replace(q, new)
|
| 60 |
+
return text
|
plugins/forcesubscribe.py
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}fsub <chat username><id>`
|
| 11 |
+
Enable ForceSub in Used Chat !
|
| 12 |
+
|
| 13 |
+
• `{i}checkfsub`
|
| 14 |
+
Check/Get Active ForceSub Setting of Used Chat.
|
| 15 |
+
|
| 16 |
+
• `{i}remfsub`
|
| 17 |
+
Remove ForceSub from Used Chat !
|
| 18 |
+
|
| 19 |
+
Note - You Need to be Admin in Both Channel/Chats
|
| 20 |
+
in order to Use ForceSubscribe.
|
| 21 |
+
"""
|
| 22 |
+
|
| 23 |
+
import re
|
| 24 |
+
|
| 25 |
+
from telethon.errors.rpcerrorlist import ChatAdminRequiredError, UserNotParticipantError
|
| 26 |
+
from telethon.tl.custom import Button
|
| 27 |
+
from telethon.tl.functions.channels import GetParticipantRequest
|
| 28 |
+
from telethon.tl.functions.messages import ExportChatInviteRequest
|
| 29 |
+
from telethon.tl.types import (
|
| 30 |
+
Channel,
|
| 31 |
+
ChannelParticipantBanned,
|
| 32 |
+
ChannelParticipantLeft,
|
| 33 |
+
User,
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
from pyUltroid.dB.forcesub_db import add_forcesub, get_forcesetting, rem_forcesub
|
| 37 |
+
|
| 38 |
+
from . import (
|
| 39 |
+
LOGS,
|
| 40 |
+
asst,
|
| 41 |
+
callback,
|
| 42 |
+
events,
|
| 43 |
+
get_string,
|
| 44 |
+
in_pattern,
|
| 45 |
+
inline_mention,
|
| 46 |
+
udB,
|
| 47 |
+
ultroid_bot,
|
| 48 |
+
ultroid_cmd,
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
CACHE = {}
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
@ultroid_cmd(pattern="fsub( (.*)|$)", admins_only=True, groups_only=True)
|
| 55 |
+
async def addfor(e):
|
| 56 |
+
match = e.pattern_match.group(1).strip()
|
| 57 |
+
if not match:
|
| 58 |
+
return await e.eor(get_string("fsub_1"), time=5)
|
| 59 |
+
try:
|
| 60 |
+
match = await e.client.parse_id(match)
|
| 61 |
+
except BaseException:
|
| 62 |
+
return await e.eor(get_string("fsub_2"), time=5)
|
| 63 |
+
add_forcesub(e.chat_id, match)
|
| 64 |
+
await e.eor("Added ForceSub in This Chat !")
|
| 65 |
+
ultroid_bot.add_handler(force_sub, events.NewMessage(incoming=True))
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
@ultroid_cmd(pattern="remfsub$")
|
| 69 |
+
async def remor(e):
|
| 70 |
+
res = rem_forcesub(e.chat_id)
|
| 71 |
+
if not res:
|
| 72 |
+
return await e.eor(get_string("fsub_3"), time=5)
|
| 73 |
+
await e.eor("Removed ForceSub...")
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
@ultroid_cmd(pattern="checkfsub$")
|
| 77 |
+
async def getfsr(e):
|
| 78 |
+
res = get_forcesetting(e.chat_id)
|
| 79 |
+
if not res:
|
| 80 |
+
return await e.eor("ForceSub is Not Active In This Chat !", time=5)
|
| 81 |
+
cha = await e.client.get_entity(int(res))
|
| 82 |
+
await e.eor(f"**ForceSub Status** : `Active`\n- **{cha.title}** `({res})`")
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
@in_pattern("fsub( (.*)|$)", owner=True)
|
| 86 |
+
async def fcall(e):
|
| 87 |
+
match = e.pattern_match.group(1).strip()
|
| 88 |
+
spli = match.split("_")
|
| 89 |
+
user = await ultroid_bot.get_entity(int(spli[0]))
|
| 90 |
+
cl = await ultroid_bot.get_entity(int(spli[1]))
|
| 91 |
+
text = f"Hi {inline_mention(user)}, You Need to Join"
|
| 92 |
+
text += f" {cl.title} in order to Chat in this Group."
|
| 93 |
+
el = (
|
| 94 |
+
f"https://t.me/{cl.username}"
|
| 95 |
+
if cl.username
|
| 96 |
+
else (await ultroid_bot(ExportChatInviteRequest(cl))).link
|
| 97 |
+
)
|
| 98 |
+
|
| 99 |
+
res = [
|
| 100 |
+
await e.builder.article(
|
| 101 |
+
title="forcesub",
|
| 102 |
+
text=text,
|
| 103 |
+
buttons=[
|
| 104 |
+
[Button.url(text=get_string("fsub_4"), url=el)],
|
| 105 |
+
[Button.inline(get_string("fsub_5"), data=f"unm_{match}")],
|
| 106 |
+
],
|
| 107 |
+
)
|
| 108 |
+
]
|
| 109 |
+
await e.answer(res)
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
@callback(re.compile("unm_(.*)"))
|
| 113 |
+
async def diesoon(e):
|
| 114 |
+
match = (e.data_match.group(1)).decode("UTF-8")
|
| 115 |
+
spli = match.split("_")
|
| 116 |
+
if e.sender_id != int(spli[0]):
|
| 117 |
+
return await e.answer(get_string("fsub_7"), alert=True)
|
| 118 |
+
try:
|
| 119 |
+
values = await ultroid_bot(GetParticipantRequest(int(spli[1]), int(spli[0])))
|
| 120 |
+
if isinstance(values.participant, ChannelParticipantLeft) or (
|
| 121 |
+
isinstance(values.participant, ChannelParticipantBanned) and values.left
|
| 122 |
+
):
|
| 123 |
+
raise UserNotParticipantError("")
|
| 124 |
+
except UserNotParticipantError:
|
| 125 |
+
return await e.answer(
|
| 126 |
+
"Please Join That Channel !\nThen Click This Button !", alert=True
|
| 127 |
+
)
|
| 128 |
+
await ultroid_bot.edit_permissions(
|
| 129 |
+
e.chat_id, int(spli[0]), send_messages=True, until_date=None
|
| 130 |
+
)
|
| 131 |
+
await e.edit(get_string("fsub_8"))
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
async def force_sub(ult):
|
| 135 |
+
if not udB.get_key("FORCESUB"):
|
| 136 |
+
return
|
| 137 |
+
user = await ult.get_sender()
|
| 138 |
+
joinchat = get_forcesetting(ult.chat_id)
|
| 139 |
+
if (not joinchat) or (isinstance(user, User) and user.bot):
|
| 140 |
+
return
|
| 141 |
+
if CACHE.get(ult.chat_id):
|
| 142 |
+
if CACHE[ult.chat_id].get(user.id):
|
| 143 |
+
CACHE[ult.chat_id].update({user.id: CACHE[ult.chat_id][user.id] + 1})
|
| 144 |
+
else:
|
| 145 |
+
CACHE[ult.chat_id].update({user.id: 1})
|
| 146 |
+
else:
|
| 147 |
+
CACHE.update({ult.chat_id: {user.id: 1}})
|
| 148 |
+
count = CACHE[ult.chat_id][user.id]
|
| 149 |
+
if count == 11:
|
| 150 |
+
CACHE[ult.chat_id][user.id] = 1
|
| 151 |
+
return
|
| 152 |
+
if count in range(2, 11):
|
| 153 |
+
return
|
| 154 |
+
try:
|
| 155 |
+
await ultroid_bot.get_permissions(int(joinchat), user.id)
|
| 156 |
+
return
|
| 157 |
+
except UserNotParticipantError:
|
| 158 |
+
pass
|
| 159 |
+
if isinstance(user, Channel):
|
| 160 |
+
try:
|
| 161 |
+
await ultroid_bot.edit_permissions(
|
| 162 |
+
ult.chat_id, user.id, view_messages=False
|
| 163 |
+
)
|
| 164 |
+
return
|
| 165 |
+
except BaseException as er:
|
| 166 |
+
LOGS.exception(er)
|
| 167 |
+
try:
|
| 168 |
+
await ultroid_bot.edit_permissions(ult.chat_id, user.id, send_messages=False)
|
| 169 |
+
except ChatAdminRequiredError:
|
| 170 |
+
return
|
| 171 |
+
except Exception as e:
|
| 172 |
+
await ult.delete()
|
| 173 |
+
LOGS.info(e)
|
| 174 |
+
res = await ultroid_bot.inline_query(asst.me.username, f"fsub {user.id}_{joinchat}")
|
| 175 |
+
await res[0].click(ult.chat_id, reply_to=ult.id)
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
if udB.get_key("FORCESUB"):
|
| 179 |
+
ultroid_bot.add_handler(force_sub, events.NewMessage(incoming=True))
|
plugins/gdrive.py
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available
|
| 9 |
+
|
| 10 |
+
• `{i}gdul <reply/file name>`
|
| 11 |
+
Reply to file to upload on Google Drive.
|
| 12 |
+
Add file name to upload on Google Drive.
|
| 13 |
+
|
| 14 |
+
• `{i}gdown <file id/link> | <filename>`
|
| 15 |
+
Download from Gdrive link or file id.
|
| 16 |
+
|
| 17 |
+
• `{i}gdsearch <file name>`
|
| 18 |
+
Search file name on Google Drive and get link.
|
| 19 |
+
|
| 20 |
+
• `{i}gdlist`
|
| 21 |
+
List all GDrive files.
|
| 22 |
+
|
| 23 |
+
• `{i}gdfolder`
|
| 24 |
+
Link to your Google Drive Folder.
|
| 25 |
+
If added then all files will be uploaded in this folder.
|
| 26 |
+
"""
|
| 27 |
+
|
| 28 |
+
import os
|
| 29 |
+
import time
|
| 30 |
+
|
| 31 |
+
from telethon.tl.types import Message
|
| 32 |
+
|
| 33 |
+
from pyUltroid.fns.gDrive import GDriveManager
|
| 34 |
+
from pyUltroid.fns.helper import time_formatter
|
| 35 |
+
|
| 36 |
+
from . import ULTConfig, asst, eod, eor, get_string, ultroid_cmd
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
@ultroid_cmd(
|
| 40 |
+
pattern="gdown( (.*)|$)",
|
| 41 |
+
fullsudo=True,
|
| 42 |
+
)
|
| 43 |
+
async def gdown(event):
|
| 44 |
+
GDrive = GDriveManager()
|
| 45 |
+
match = event.pattern_match.group(1).strip()
|
| 46 |
+
if not match:
|
| 47 |
+
return await eod(event, "`Give file id or Gdrive link to download from!`")
|
| 48 |
+
filename = match.split(" | ")[1].strip() if " | " in match else None
|
| 49 |
+
eve = await event.eor(get_string("com_1"))
|
| 50 |
+
_start = time.time()
|
| 51 |
+
status, response = await GDrive._download_file(eve, match, filename)
|
| 52 |
+
if not status:
|
| 53 |
+
return await eve.edit(response)
|
| 54 |
+
await eve.edit(
|
| 55 |
+
f"`Downloaded ``{response}`` in {time_formatter((time.time() - _start)*1000)}`"
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
@ultroid_cmd(
|
| 60 |
+
pattern="gdlist$",
|
| 61 |
+
fullsudo=True,
|
| 62 |
+
)
|
| 63 |
+
async def files(event):
|
| 64 |
+
GDrive = GDriveManager()
|
| 65 |
+
if not os.path.exists(GDrive.token_file):
|
| 66 |
+
return await event.eor(get_string("gdrive_6").format(asst.me.username))
|
| 67 |
+
eve = await event.eor(get_string("com_1"))
|
| 68 |
+
msg = ""
|
| 69 |
+
if files := GDrive._list_files:
|
| 70 |
+
msg += f"{len(files.keys())} files found in gdrive.\n\n"
|
| 71 |
+
for _ in files:
|
| 72 |
+
msg += f"> [{files[_]}]({_})\n"
|
| 73 |
+
else:
|
| 74 |
+
msg += "Nothing in Gdrive"
|
| 75 |
+
if len(msg) < 4096:
|
| 76 |
+
await eve.edit(msg, link_preview=False)
|
| 77 |
+
else:
|
| 78 |
+
with open("drive-files.txt", "w") as f:
|
| 79 |
+
f.write(
|
| 80 |
+
msg.replace("[", "File Name: ")
|
| 81 |
+
.replace("](", "\n» Link: ")
|
| 82 |
+
.replace(")\n", "\n\n")
|
| 83 |
+
)
|
| 84 |
+
try:
|
| 85 |
+
await eve.delete()
|
| 86 |
+
except BaseException:
|
| 87 |
+
pass
|
| 88 |
+
await event.client.send_file(
|
| 89 |
+
event.chat_id,
|
| 90 |
+
"drive-files.txt",
|
| 91 |
+
thumb=ULTConfig.thumb,
|
| 92 |
+
reply_to=event,
|
| 93 |
+
)
|
| 94 |
+
os.remove("drive-files.txt")
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
@ultroid_cmd(
|
| 98 |
+
pattern="gdul( (.*)|$)",
|
| 99 |
+
fullsudo=True,
|
| 100 |
+
)
|
| 101 |
+
async def _(event):
|
| 102 |
+
GDrive = GDriveManager()
|
| 103 |
+
if not os.path.exists(GDrive.token_file):
|
| 104 |
+
return await eod(event, get_string("gdrive_6").format(asst.me.username))
|
| 105 |
+
input_file = event.pattern_match.group(1).strip() or await event.get_reply_message()
|
| 106 |
+
if not input_file:
|
| 107 |
+
return await eod(event, "`Reply to file or give its location.`")
|
| 108 |
+
mone = await event.eor(get_string("com_1"))
|
| 109 |
+
if isinstance(input_file, Message):
|
| 110 |
+
location = "resources/downloads"
|
| 111 |
+
if input_file.photo:
|
| 112 |
+
filename = await input_file.download_media(location)
|
| 113 |
+
else:
|
| 114 |
+
filename = input_file.file.name
|
| 115 |
+
if not filename:
|
| 116 |
+
filename = str(round(time.time()))
|
| 117 |
+
filename = f"{location}/{filename}"
|
| 118 |
+
try:
|
| 119 |
+
filename, downloaded_in = await event.client.fast_downloader(
|
| 120 |
+
file=input_file.media.document,
|
| 121 |
+
filename=filename,
|
| 122 |
+
show_progress=True,
|
| 123 |
+
event=mone,
|
| 124 |
+
message=get_string("com_5"),
|
| 125 |
+
)
|
| 126 |
+
filename = filename.name
|
| 127 |
+
except Exception as e:
|
| 128 |
+
return await eor(mone, str(e), time=10)
|
| 129 |
+
await mone.edit(
|
| 130 |
+
f"`Downloaded to ``{filename}`.`",
|
| 131 |
+
)
|
| 132 |
+
else:
|
| 133 |
+
filename = input_file.strip()
|
| 134 |
+
if not os.path.exists(filename):
|
| 135 |
+
return await eod(
|
| 136 |
+
mone,
|
| 137 |
+
"File Not found in local server. Give me a file path :((",
|
| 138 |
+
time=5,
|
| 139 |
+
)
|
| 140 |
+
folder_id = None
|
| 141 |
+
if os.path.isdir(filename):
|
| 142 |
+
files = os.listdir(filename)
|
| 143 |
+
if not files:
|
| 144 |
+
return await eod(
|
| 145 |
+
mone, "`Requested directory is empty. Can't create empty directory.`"
|
| 146 |
+
)
|
| 147 |
+
folder_id = GDrive.create_directory(filename)
|
| 148 |
+
c = 0
|
| 149 |
+
for files in sorted(files):
|
| 150 |
+
file = f"{filename}/{files}"
|
| 151 |
+
if not os.path.isdir(file):
|
| 152 |
+
try:
|
| 153 |
+
await GDrive._upload_file(mone, path=file, folder_id=folder_id)
|
| 154 |
+
c += 1
|
| 155 |
+
except Exception as e:
|
| 156 |
+
return await mone.edit(
|
| 157 |
+
f"Exception occurred while uploading to gDrive {e}"
|
| 158 |
+
)
|
| 159 |
+
return await mone.edit(
|
| 160 |
+
f"`Uploaded `[{filename}](https://drive.google.com/folderview?id={folder_id})` with {c} files.`"
|
| 161 |
+
)
|
| 162 |
+
try:
|
| 163 |
+
g_drive_link = await GDrive._upload_file(
|
| 164 |
+
mone,
|
| 165 |
+
filename,
|
| 166 |
+
)
|
| 167 |
+
await mone.edit(
|
| 168 |
+
get_string("gdrive_7").format(filename.split("/")[-1], g_drive_link)
|
| 169 |
+
)
|
| 170 |
+
except Exception as e:
|
| 171 |
+
await mone.edit(f"Exception occurred while uploading to gDrive {e}")
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
@ultroid_cmd(
|
| 175 |
+
pattern="gdsearch( (.*)|$)",
|
| 176 |
+
fullsudo=True,
|
| 177 |
+
)
|
| 178 |
+
async def _(event):
|
| 179 |
+
GDrive = GDriveManager()
|
| 180 |
+
if not os.path.exists(GDrive.token_file):
|
| 181 |
+
return await event.eor(get_string("gdrive_6").format(asst.me.username))
|
| 182 |
+
input_str = event.pattern_match.group(1).strip()
|
| 183 |
+
if not input_str:
|
| 184 |
+
return await event.eor("`Give filename to search on GDrive...`")
|
| 185 |
+
eve = await event.eor(f"`Searching for {input_str} in G-Drive...`")
|
| 186 |
+
files = GDrive.search(input_str)
|
| 187 |
+
msg = ""
|
| 188 |
+
if files:
|
| 189 |
+
msg += (
|
| 190 |
+
f"{len(files.keys())} files with {input_str} in title found in GDrive.\n\n"
|
| 191 |
+
)
|
| 192 |
+
for _ in files:
|
| 193 |
+
msg += f"> [{files[_]}]({_})\n"
|
| 194 |
+
else:
|
| 195 |
+
msg += f"`No files with title {input_str}`"
|
| 196 |
+
if len(msg) < 4096:
|
| 197 |
+
await eve.eor(msg, link_preview=False)
|
| 198 |
+
else:
|
| 199 |
+
with open("drive-files.txt", "w") as f:
|
| 200 |
+
f.write(
|
| 201 |
+
msg.replace("[", "File Name: ")
|
| 202 |
+
.replace("](", "\n» Link: ")
|
| 203 |
+
.replace(")\n", "\n\n")
|
| 204 |
+
)
|
| 205 |
+
try:
|
| 206 |
+
await eve.delete()
|
| 207 |
+
except BaseException:
|
| 208 |
+
pass
|
| 209 |
+
await event.client.send_file(
|
| 210 |
+
event.chat_id,
|
| 211 |
+
f"{input_str}.txt",
|
| 212 |
+
thumb=ULTConfig.thumb,
|
| 213 |
+
reply_to=event,
|
| 214 |
+
)
|
| 215 |
+
os.remove(f"{input_str}.txt")
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
@ultroid_cmd(
|
| 219 |
+
pattern="gdfolder$",
|
| 220 |
+
fullsudo=True,
|
| 221 |
+
)
|
| 222 |
+
async def _(event):
|
| 223 |
+
GDrive = GDriveManager()
|
| 224 |
+
if not os.path.exists(GDrive.token_file):
|
| 225 |
+
return await event.eor(get_string("gdrive_6").format(asst.me.username))
|
| 226 |
+
if GDrive.folder_id:
|
| 227 |
+
await event.eor(
|
| 228 |
+
"`Your G-Drive Folder link : `\n"
|
| 229 |
+
+ GDrive._create_folder_link(GDrive.folder_id)
|
| 230 |
+
)
|
| 231 |
+
else:
|
| 232 |
+
await eod(event, "Set FOLDERID from your Assistant bot's Settings ")
|
plugins/giftools.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available
|
| 9 |
+
|
| 10 |
+
•`{i}invertgif`
|
| 11 |
+
Make Gif Inverted(negative).
|
| 12 |
+
|
| 13 |
+
•`{i}bwgif`
|
| 14 |
+
Make Gif black and white
|
| 15 |
+
|
| 16 |
+
•`{i}rvgif`
|
| 17 |
+
Reverse a gif
|
| 18 |
+
|
| 19 |
+
•`{i}vtog`
|
| 20 |
+
Reply To Video , It will Create Gif
|
| 21 |
+
Video to Gif
|
| 22 |
+
|
| 23 |
+
•`{i}gif <query>`
|
| 24 |
+
Send video regarding to query.
|
| 25 |
+
"""
|
| 26 |
+
import os
|
| 27 |
+
import random
|
| 28 |
+
import time
|
| 29 |
+
from datetime import datetime as dt
|
| 30 |
+
|
| 31 |
+
from . import HNDLR, LOGS, bash, downloader, get_string, mediainfo, ultroid_cmd
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
@ultroid_cmd(pattern="(bw|invert)gif$")
|
| 35 |
+
async def igif(e):
|
| 36 |
+
match = e.pattern_match.group(1).strip()
|
| 37 |
+
a = await e.get_reply_message()
|
| 38 |
+
if not (a and a.media):
|
| 39 |
+
return await e.eor("`Reply To gif only`", time=5)
|
| 40 |
+
wut = mediainfo(a.media)
|
| 41 |
+
if "gif" not in wut:
|
| 42 |
+
return await e.eor("`Reply To Gif Only`", time=5)
|
| 43 |
+
xx = await e.eor(get_string("com_1"))
|
| 44 |
+
z = await a.download_media()
|
| 45 |
+
if match == "bw":
|
| 46 |
+
cmd = f'ffmpeg -i "{z}" -vf format=gray ult.gif -y'
|
| 47 |
+
else:
|
| 48 |
+
cmd = f'ffmpeg -i "{z}" -vf lutyuv="y=negval:u=negval:v=negval" ult.gif -y'
|
| 49 |
+
try:
|
| 50 |
+
await bash(cmd)
|
| 51 |
+
await e.client.send_file(e.chat_id, "ult.gif", supports_streaming=True)
|
| 52 |
+
os.remove(z)
|
| 53 |
+
os.remove("ult.gif")
|
| 54 |
+
await xx.delete()
|
| 55 |
+
except Exception as er:
|
| 56 |
+
LOGS.info(er)
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
@ultroid_cmd(pattern="rvgif$")
|
| 60 |
+
async def reverse_gif(event):
|
| 61 |
+
a = await event.get_reply_message()
|
| 62 |
+
if not (a and a.media) and "video" not in mediainfo(a.media):
|
| 63 |
+
return await event.eor("`Reply To Video only`", time=5)
|
| 64 |
+
msg = await event.eor(get_string("com_1"))
|
| 65 |
+
file = await a.download_media()
|
| 66 |
+
await bash(f'ffmpeg -i "{file}" -vf reverse -af areverse reversed.mp4 -y')
|
| 67 |
+
await event.respond("- **Reversed Video/GIF**", file="reversed.mp4")
|
| 68 |
+
await msg.delete()
|
| 69 |
+
os.remove(file)
|
| 70 |
+
os.remove("reversed.mp4")
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
@ultroid_cmd(pattern="gif( (.*)|$)")
|
| 74 |
+
async def gifs(ult):
|
| 75 |
+
get = ult.pattern_match.group(1).strip()
|
| 76 |
+
xx = random.randint(0, 5)
|
| 77 |
+
n = 0
|
| 78 |
+
if ";" in get:
|
| 79 |
+
try:
|
| 80 |
+
n = int(get.split(";")[-1])
|
| 81 |
+
except IndexError:
|
| 82 |
+
pass
|
| 83 |
+
if not get:
|
| 84 |
+
return await ult.eor(f"`{HNDLR}gif <query>`")
|
| 85 |
+
m = await ult.eor(get_string("com_2"))
|
| 86 |
+
gifs = await ult.client.inline_query("gif", get)
|
| 87 |
+
if not n:
|
| 88 |
+
await gifs[xx].click(
|
| 89 |
+
ult.chat_id, reply_to=ult.reply_to_msg_id, silent=True, hide_via=True
|
| 90 |
+
)
|
| 91 |
+
else:
|
| 92 |
+
for x in range(n):
|
| 93 |
+
await gifs[x].click(
|
| 94 |
+
ult.chat_id, reply_to=ult.reply_to_msg_id, silent=True, hide_via=True
|
| 95 |
+
)
|
| 96 |
+
await m.delete()
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@ultroid_cmd(pattern="vtog$")
|
| 100 |
+
async def vtogif(e):
|
| 101 |
+
a = await e.get_reply_message()
|
| 102 |
+
if not (a and a.media):
|
| 103 |
+
return await e.eor("`Reply To video only`", time=5)
|
| 104 |
+
wut = mediainfo(a.media)
|
| 105 |
+
if "video" not in wut:
|
| 106 |
+
return await e.eor("`Reply To Video Only`", time=5)
|
| 107 |
+
xx = await e.eor(get_string("com_1"))
|
| 108 |
+
dur = a.media.document.attributes[0].duration
|
| 109 |
+
tt = time.time()
|
| 110 |
+
if int(dur) < 120:
|
| 111 |
+
z = await a.download_media()
|
| 112 |
+
await bash(
|
| 113 |
+
f'ffmpeg -i {z} -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 ult.gif -y'
|
| 114 |
+
)
|
| 115 |
+
else:
|
| 116 |
+
filename = a.file.name
|
| 117 |
+
if not filename:
|
| 118 |
+
filename = "video_" + dt.now().isoformat("_", "seconds") + ".mp4"
|
| 119 |
+
vid = await downloader(filename, a.media.document, xx, tt, get_string("com_5"))
|
| 120 |
+
z = vid.name
|
| 121 |
+
await bash(
|
| 122 |
+
f'ffmpeg -ss 3 -t 100 -i {z} -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 ult.gif'
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
+
await e.client.send_file(e.chat_id, "ult.gif", support_stream=True)
|
| 126 |
+
os.remove(z)
|
| 127 |
+
os.remove("ult.gif")
|
| 128 |
+
await xx.delete()
|
plugins/glitch.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
•`{i}glitch <reply to media>`
|
| 11 |
+
gives a glitchy gif.
|
| 12 |
+
"""
|
| 13 |
+
import os
|
| 14 |
+
|
| 15 |
+
from . import bash, get_string, mediainfo, ultroid_cmd
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
@ultroid_cmd(pattern="glitch$")
|
| 19 |
+
async def _(e):
|
| 20 |
+
try:
|
| 21 |
+
import glitch_me # ignore :pylint
|
| 22 |
+
except ModuleNotFoundError:
|
| 23 |
+
await bash(
|
| 24 |
+
"pip install -e git+https://github.com/1Danish-00/glitch_me.git#egg=glitch_me"
|
| 25 |
+
)
|
| 26 |
+
reply = await e.get_reply_message()
|
| 27 |
+
if not reply or not reply.media:
|
| 28 |
+
return await e.eor(get_string("cvt_3"))
|
| 29 |
+
xx = await e.eor(get_string("glitch_1"))
|
| 30 |
+
wut = mediainfo(reply.media)
|
| 31 |
+
if wut.startswith(("pic", "sticker")):
|
| 32 |
+
ok = await reply.download_media()
|
| 33 |
+
elif reply.document and reply.document.thumbs:
|
| 34 |
+
ok = await reply.download_media(thumb=-1)
|
| 35 |
+
else:
|
| 36 |
+
return await xx.eor(get_string("com_4"))
|
| 37 |
+
cmd = f"glitch_me gif --line_count 200 -f 10 -d 50 '{ok}' ult.gif"
|
| 38 |
+
await bash(cmd)
|
| 39 |
+
await e.reply(file="ult.gif", force_document=False)
|
| 40 |
+
await xx.delete()
|
| 41 |
+
os.remove(ok)
|
| 42 |
+
os.remove("ult.gif")
|
plugins/globaltools.py
ADDED
|
@@ -0,0 +1,753 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}gban <reply user/ username>`
|
| 11 |
+
• `{i}ungban`
|
| 12 |
+
Ban/Unban Globally.
|
| 13 |
+
|
| 14 |
+
• `{i}gstat <reply to user/userid/username>`
|
| 15 |
+
Check if user is GBanned.
|
| 16 |
+
|
| 17 |
+
• `{i}listgban` : List all GBanned users.
|
| 18 |
+
|
| 19 |
+
• `{i}gmute` | `{i}ungmute` <reply user/ username>
|
| 20 |
+
Mute/UnMute Globally.
|
| 21 |
+
|
| 22 |
+
• `{i}gkick <reply/username>` `Globally Kick User`
|
| 23 |
+
• `{i}gcast <text/reply>` `Globally Send msg in all grps`
|
| 24 |
+
|
| 25 |
+
• `{i}gadmincast <text/reply>` `Globally broadcast in your admin chats`
|
| 26 |
+
• `{i}gucast <text/reply>` `Globally send msg in all pm users`
|
| 27 |
+
|
| 28 |
+
• `{i}gblacklist <chat id/username/nothing (for current chat)`
|
| 29 |
+
Add chat to blacklist and ignores global broadcast.
|
| 30 |
+
• `{i}ungblacklist` `Remove the chat from blacklist.`
|
| 31 |
+
|
| 32 |
+
• `{i}gpromote <reply to user> <channel/group/all> <rank>`
|
| 33 |
+
globally promote user where you are admin
|
| 34 |
+
- Set whether To promote only in groups/channels/all.
|
| 35 |
+
Eg- `gpromote group boss` ~ promotes user in all grps.
|
| 36 |
+
`gpromote @username all sar` ~ promote the user in all group & channel
|
| 37 |
+
• `{i}gdemote` - `demote user globally`
|
| 38 |
+
"""
|
| 39 |
+
import asyncio
|
| 40 |
+
import os
|
| 41 |
+
|
| 42 |
+
from telethon.errors.rpcerrorlist import ChatAdminRequiredError, FloodWaitError
|
| 43 |
+
from telethon.tl.functions.channels import EditAdminRequest
|
| 44 |
+
from telethon.tl.functions.contacts import BlockRequest, UnblockRequest
|
| 45 |
+
from telethon.tl.types import ChatAdminRights, User
|
| 46 |
+
|
| 47 |
+
from pyUltroid.dB import DEVLIST
|
| 48 |
+
from pyUltroid.dB.base import KeyManager
|
| 49 |
+
from pyUltroid.dB.gban_mute_db import (
|
| 50 |
+
gban,
|
| 51 |
+
gmute,
|
| 52 |
+
is_gbanned,
|
| 53 |
+
is_gmuted,
|
| 54 |
+
list_gbanned,
|
| 55 |
+
ungban,
|
| 56 |
+
ungmute,
|
| 57 |
+
)
|
| 58 |
+
from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button
|
| 59 |
+
|
| 60 |
+
from . import (
|
| 61 |
+
HNDLR,
|
| 62 |
+
LOGS,
|
| 63 |
+
NOSPAM_CHAT,
|
| 64 |
+
OWNER_NAME,
|
| 65 |
+
eod,
|
| 66 |
+
eor,
|
| 67 |
+
get_string,
|
| 68 |
+
inline_mention,
|
| 69 |
+
ultroid_bot,
|
| 70 |
+
ultroid_cmd,
|
| 71 |
+
)
|
| 72 |
+
from ._inline import something
|
| 73 |
+
|
| 74 |
+
_gpromote_rights = ChatAdminRights(
|
| 75 |
+
add_admins=False,
|
| 76 |
+
invite_users=True,
|
| 77 |
+
change_info=False,
|
| 78 |
+
ban_users=True,
|
| 79 |
+
delete_messages=True,
|
| 80 |
+
pin_messages=True,
|
| 81 |
+
)
|
| 82 |
+
|
| 83 |
+
_gdemote_rights = ChatAdminRights(
|
| 84 |
+
add_admins=False,
|
| 85 |
+
invite_users=False,
|
| 86 |
+
change_info=False,
|
| 87 |
+
ban_users=False,
|
| 88 |
+
delete_messages=False,
|
| 89 |
+
pin_messages=False,
|
| 90 |
+
)
|
| 91 |
+
|
| 92 |
+
keym = KeyManager("GBLACKLISTS", cast=list)
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
@ultroid_cmd(pattern="gpromote( (.*)|$)", fullsudo=True)
|
| 96 |
+
async def _(e):
|
| 97 |
+
x = e.pattern_match.group(1).strip()
|
| 98 |
+
ultroid_bot = e.client
|
| 99 |
+
if not x:
|
| 100 |
+
return await e.eor(get_string("schdl_2"), time=5)
|
| 101 |
+
user = await e.get_reply_message()
|
| 102 |
+
if user:
|
| 103 |
+
ev = await e.eor("`Promoting Replied User Globally`")
|
| 104 |
+
ok = e.text.split()
|
| 105 |
+
key = "all"
|
| 106 |
+
if len(ok) > 1 and (("group" in ok[1]) or ("channel" in ok[1])):
|
| 107 |
+
key = ok[1]
|
| 108 |
+
rank = ok[2] if len(ok) > 2 else "AdMin"
|
| 109 |
+
c = 0
|
| 110 |
+
user.id = user.peer_id.user_id if e.is_private else user.from_id.user_id
|
| 111 |
+
async for x in e.client.iter_dialogs():
|
| 112 |
+
if (
|
| 113 |
+
"group" in key.lower()
|
| 114 |
+
and x.is_group
|
| 115 |
+
or "group" not in key.lower()
|
| 116 |
+
and "channel" in key.lower()
|
| 117 |
+
and x.is_channel
|
| 118 |
+
):
|
| 119 |
+
try:
|
| 120 |
+
await e.client(
|
| 121 |
+
EditAdminRequest(
|
| 122 |
+
x.id,
|
| 123 |
+
user.id,
|
| 124 |
+
_gpromote_rights,
|
| 125 |
+
rank,
|
| 126 |
+
),
|
| 127 |
+
)
|
| 128 |
+
c += 1
|
| 129 |
+
except BaseException:
|
| 130 |
+
pass
|
| 131 |
+
elif (
|
| 132 |
+
("group" not in key.lower() or x.is_group)
|
| 133 |
+
and (
|
| 134 |
+
"group" in key.lower()
|
| 135 |
+
or "channel" not in key.lower()
|
| 136 |
+
or x.is_channel
|
| 137 |
+
)
|
| 138 |
+
and (
|
| 139 |
+
"group" in key.lower()
|
| 140 |
+
or "channel" in key.lower()
|
| 141 |
+
or x.is_group
|
| 142 |
+
or x.is_channel
|
| 143 |
+
)
|
| 144 |
+
):
|
| 145 |
+
try:
|
| 146 |
+
await e.client(
|
| 147 |
+
EditAdminRequest(
|
| 148 |
+
x.id,
|
| 149 |
+
user.id,
|
| 150 |
+
_gpromote_rights,
|
| 151 |
+
rank,
|
| 152 |
+
),
|
| 153 |
+
)
|
| 154 |
+
c += 1
|
| 155 |
+
except Exception as er:
|
| 156 |
+
LOGS.info(er)
|
| 157 |
+
await eor(ev, f"Promoted The Replied Users in Total : {c} {key} chats")
|
| 158 |
+
else:
|
| 159 |
+
k = e.text.split()
|
| 160 |
+
if not k[1]:
|
| 161 |
+
return await eor(
|
| 162 |
+
e, "`Give someone's username/id or replied to user.", time=5
|
| 163 |
+
)
|
| 164 |
+
user = k[1]
|
| 165 |
+
if user.isdigit():
|
| 166 |
+
user = int(user)
|
| 167 |
+
try:
|
| 168 |
+
name = await e.client.get_entity(user)
|
| 169 |
+
except BaseException:
|
| 170 |
+
return await e.eor(f"`No User Found Regarding {user}`", time=5)
|
| 171 |
+
ev = await e.eor(f"`Promoting {name.first_name} globally.`")
|
| 172 |
+
key = "all"
|
| 173 |
+
if len(k) > 2 and (("group" in k[2]) or ("channel" in k[2])):
|
| 174 |
+
key = k[2]
|
| 175 |
+
rank = k[3] if len(k) > 3 else "AdMin"
|
| 176 |
+
c = 0
|
| 177 |
+
async for x in e.client.iter_dialogs():
|
| 178 |
+
if (
|
| 179 |
+
"group" in key.lower()
|
| 180 |
+
and x.is_group
|
| 181 |
+
or "group" not in key.lower()
|
| 182 |
+
and "channel" in key.lower()
|
| 183 |
+
and x.is_channel
|
| 184 |
+
or "group" not in key.lower()
|
| 185 |
+
and "channel" not in key.lower()
|
| 186 |
+
and (x.is_group or x.is_channel)
|
| 187 |
+
):
|
| 188 |
+
try:
|
| 189 |
+
await ultroid_bot(
|
| 190 |
+
EditAdminRequest(
|
| 191 |
+
x.id,
|
| 192 |
+
user,
|
| 193 |
+
_gpromote_rights,
|
| 194 |
+
rank,
|
| 195 |
+
),
|
| 196 |
+
)
|
| 197 |
+
c += 1
|
| 198 |
+
except BaseException:
|
| 199 |
+
pass
|
| 200 |
+
await eor(ev, f"Promoted {name.first_name} in Total : {c} {key} chats.")
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
@ultroid_cmd(pattern="gdemote( (.*)|$)", fullsudo=True)
|
| 204 |
+
async def _(e):
|
| 205 |
+
x = e.pattern_match.group(1).strip()
|
| 206 |
+
ultroid_bot = e.client
|
| 207 |
+
if not x:
|
| 208 |
+
return await e.eor(get_string("schdl_2"), time=5)
|
| 209 |
+
user = await e.get_reply_message()
|
| 210 |
+
if user:
|
| 211 |
+
user.id = user.peer_id.user_id if e.is_private else user.from_id.user_id
|
| 212 |
+
ev = await e.eor("`Demoting Replied User Globally`")
|
| 213 |
+
ok = e.text.split()
|
| 214 |
+
key = "all"
|
| 215 |
+
if len(ok) > 1 and (("group" in ok[1]) or ("channel" in ok[1])):
|
| 216 |
+
key = ok[1]
|
| 217 |
+
rank = "Not AdMin"
|
| 218 |
+
c = 0
|
| 219 |
+
async for x in e.client.iter_dialogs():
|
| 220 |
+
if (
|
| 221 |
+
"group" in key.lower()
|
| 222 |
+
and x.is_group
|
| 223 |
+
or "group" not in key.lower()
|
| 224 |
+
and "channel" in key.lower()
|
| 225 |
+
and x.is_channel
|
| 226 |
+
or "group" not in key.lower()
|
| 227 |
+
and "channel" not in key.lower()
|
| 228 |
+
and (x.is_group or x.is_channel)
|
| 229 |
+
):
|
| 230 |
+
try:
|
| 231 |
+
await ultroid_bot(
|
| 232 |
+
EditAdminRequest(
|
| 233 |
+
x.id,
|
| 234 |
+
user.id,
|
| 235 |
+
_gdemote_rights,
|
| 236 |
+
rank,
|
| 237 |
+
),
|
| 238 |
+
)
|
| 239 |
+
c += 1
|
| 240 |
+
except BaseException:
|
| 241 |
+
pass
|
| 242 |
+
await eor(ev, f"Demoted The Replied Users in Total : {c} {key} chats")
|
| 243 |
+
else:
|
| 244 |
+
k = e.text.split()
|
| 245 |
+
if not k[1]:
|
| 246 |
+
return await eor(
|
| 247 |
+
e, "`Give someone's username/id or replied to user.", time=5
|
| 248 |
+
)
|
| 249 |
+
user = k[1]
|
| 250 |
+
if user.isdigit():
|
| 251 |
+
user = int(user)
|
| 252 |
+
try:
|
| 253 |
+
name = await ultroid_bot.get_entity(user)
|
| 254 |
+
except BaseException:
|
| 255 |
+
return await e.eor(f"`No User Found Regarding {user}`", time=5)
|
| 256 |
+
ev = await e.eor(f"`Demoting {name.first_name} globally.`")
|
| 257 |
+
key = "all"
|
| 258 |
+
if len(k) > 2 and (("group" in k[2]) or ("channel" in k[2])):
|
| 259 |
+
key = k[2]
|
| 260 |
+
rank = "Not AdMin"
|
| 261 |
+
c = 0
|
| 262 |
+
async for x in ultroid_bot.iter_dialogs():
|
| 263 |
+
if (
|
| 264 |
+
"group" in key.lower()
|
| 265 |
+
and x.is_group
|
| 266 |
+
or "group" not in key.lower()
|
| 267 |
+
and "channel" in key.lower()
|
| 268 |
+
and x.is_channel
|
| 269 |
+
or "group" not in key.lower()
|
| 270 |
+
and "channel" not in key.lower()
|
| 271 |
+
and (x.is_group or x.is_channel)
|
| 272 |
+
):
|
| 273 |
+
try:
|
| 274 |
+
await ultroid_bot(
|
| 275 |
+
EditAdminRequest(
|
| 276 |
+
x.id,
|
| 277 |
+
user,
|
| 278 |
+
_gdemote_rights,
|
| 279 |
+
rank,
|
| 280 |
+
),
|
| 281 |
+
)
|
| 282 |
+
c += 1
|
| 283 |
+
except BaseException:
|
| 284 |
+
pass
|
| 285 |
+
await eor(ev, f"Demoted {name.first_name} in Total : {c} {key} chats.")
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
@ultroid_cmd(pattern="ungban( (.*)|$)", fullsudo=True)
|
| 289 |
+
async def _(e):
|
| 290 |
+
xx = await e.eor("`UnGbanning...`")
|
| 291 |
+
match = e.pattern_match.group(1).strip()
|
| 292 |
+
peer = None
|
| 293 |
+
if e.reply_to_msg_id:
|
| 294 |
+
userid = (await e.get_reply_message()).sender_id
|
| 295 |
+
elif match:
|
| 296 |
+
try:
|
| 297 |
+
userid = int(match)
|
| 298 |
+
except ValueError:
|
| 299 |
+
userid = match
|
| 300 |
+
try:
|
| 301 |
+
userid = (await e.client.get_entity(userid)).id
|
| 302 |
+
except Exception as er:
|
| 303 |
+
return await xx.edit(f"Failed to get User...\nError: {er}")
|
| 304 |
+
elif e.is_private:
|
| 305 |
+
userid = e.chat_id
|
| 306 |
+
else:
|
| 307 |
+
return await xx.eor("`Reply to some msg or add their id.`", time=5)
|
| 308 |
+
if not is_gbanned(userid):
|
| 309 |
+
return await xx.edit("`User/Channel is not Gbanned...`")
|
| 310 |
+
try:
|
| 311 |
+
if not peer:
|
| 312 |
+
peer = await e.client.get_entity(userid)
|
| 313 |
+
name = inline_mention(peer)
|
| 314 |
+
except BaseException:
|
| 315 |
+
userid = int(userid)
|
| 316 |
+
name = str(userid)
|
| 317 |
+
chats = 0
|
| 318 |
+
if e.client._dialogs:
|
| 319 |
+
dialog = e.client._dialogs
|
| 320 |
+
else:
|
| 321 |
+
dialog = await e.client.get_dialogs()
|
| 322 |
+
e.client._dialogs.extend(dialog)
|
| 323 |
+
for ggban in dialog:
|
| 324 |
+
if ggban.is_group or ggban.is_channel:
|
| 325 |
+
try:
|
| 326 |
+
await e.client.edit_permissions(ggban.id, userid, view_messages=True)
|
| 327 |
+
chats += 1
|
| 328 |
+
except FloodWaitError as fw:
|
| 329 |
+
LOGS.info(
|
| 330 |
+
f"[FLOOD_WAIT_ERROR] : on Ungban\nSleeping for {fw.seconds+10}"
|
| 331 |
+
)
|
| 332 |
+
await asyncio.sleep(fw.seconds + 10)
|
| 333 |
+
try:
|
| 334 |
+
await e.client.edit_permissions(
|
| 335 |
+
ggban.id, userid, view_messages=True
|
| 336 |
+
)
|
| 337 |
+
chats += 1
|
| 338 |
+
except BaseException as er:
|
| 339 |
+
LOGS.exception(er)
|
| 340 |
+
except (ChatAdminRequiredError, ValueError):
|
| 341 |
+
pass
|
| 342 |
+
except BaseException as er:
|
| 343 |
+
LOGS.exception(er)
|
| 344 |
+
ungban(userid)
|
| 345 |
+
if isinstance(peer, User):
|
| 346 |
+
await e.client(UnblockRequest(userid))
|
| 347 |
+
await xx.edit(
|
| 348 |
+
f"`Ungbaned` {name} in {chats} `chats.\nRemoved from gbanwatch.`",
|
| 349 |
+
)
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
@ultroid_cmd(pattern="gban( (.*)|$)", fullsudo=True)
|
| 353 |
+
async def _(e):
|
| 354 |
+
xx = await e.eor("`Gbanning...`")
|
| 355 |
+
reason = ""
|
| 356 |
+
if e.reply_to_msg_id:
|
| 357 |
+
userid = (await e.get_reply_message()).sender_id
|
| 358 |
+
try:
|
| 359 |
+
reason = e.text.split(" ", maxsplit=1)[1]
|
| 360 |
+
except IndexError:
|
| 361 |
+
pass
|
| 362 |
+
elif e.pattern_match.group(1).strip():
|
| 363 |
+
usr = e.text.split(maxsplit=2)[1]
|
| 364 |
+
try:
|
| 365 |
+
userid = await e.client.parse_id(usr)
|
| 366 |
+
except ValueError:
|
| 367 |
+
userid = usr
|
| 368 |
+
try:
|
| 369 |
+
reason = e.text.split(maxsplit=2)[2]
|
| 370 |
+
except IndexError:
|
| 371 |
+
pass
|
| 372 |
+
elif e.is_private:
|
| 373 |
+
userid = e.chat_id
|
| 374 |
+
try:
|
| 375 |
+
reason = e.text.split(" ", maxsplit=1)[1]
|
| 376 |
+
except IndexError:
|
| 377 |
+
pass
|
| 378 |
+
else:
|
| 379 |
+
return await xx.eor("`Reply to some msg or add their id.`", time=5)
|
| 380 |
+
user = None
|
| 381 |
+
try:
|
| 382 |
+
user = await e.client.get_entity(userid)
|
| 383 |
+
name = inline_mention(user)
|
| 384 |
+
except BaseException:
|
| 385 |
+
userid = int(userid)
|
| 386 |
+
name = str(userid)
|
| 387 |
+
chats = 0
|
| 388 |
+
if userid == ultroid_bot.uid:
|
| 389 |
+
return await xx.eor("`I can't gban myself.`", time=3)
|
| 390 |
+
elif userid in DEVLIST:
|
| 391 |
+
return await xx.eor("`I can't gban my Developers.`", time=3)
|
| 392 |
+
elif is_gbanned(userid):
|
| 393 |
+
return await eod(
|
| 394 |
+
xx,
|
| 395 |
+
"`User is already gbanned and added to gbanwatch.`",
|
| 396 |
+
time=4,
|
| 397 |
+
)
|
| 398 |
+
if e.client._dialogs:
|
| 399 |
+
dialog = e.client._dialogs
|
| 400 |
+
else:
|
| 401 |
+
dialog = await e.client.get_dialogs()
|
| 402 |
+
e.client._dialogs.extend(dialog)
|
| 403 |
+
for ggban in dialog:
|
| 404 |
+
if ggban.is_group or ggban.is_channel:
|
| 405 |
+
try:
|
| 406 |
+
await e.client.edit_permissions(ggban.id, userid, view_messages=False)
|
| 407 |
+
chats += 1
|
| 408 |
+
except FloodWaitError as fw:
|
| 409 |
+
LOGS.info(
|
| 410 |
+
f"[FLOOD_WAIT_ERROR] : on GBAN Command\nSleeping for {fw.seconds+10}"
|
| 411 |
+
)
|
| 412 |
+
await asyncio.sleep(fw.seconds + 10)
|
| 413 |
+
try:
|
| 414 |
+
await e.client.edit_permissions(
|
| 415 |
+
ggban.id, userid, view_messages=False
|
| 416 |
+
)
|
| 417 |
+
chats += 1
|
| 418 |
+
except BaseException as er:
|
| 419 |
+
LOGS.exception(er)
|
| 420 |
+
except (ChatAdminRequiredError, ValueError):
|
| 421 |
+
pass
|
| 422 |
+
except BaseException as er:
|
| 423 |
+
LOGS.exception(er)
|
| 424 |
+
gban(userid, reason)
|
| 425 |
+
if isinstance(user, User):
|
| 426 |
+
await e.client(BlockRequest(userid))
|
| 427 |
+
gb_msg = f"**#Gbanned** {name} `in {chats} chats and added to gbanwatch!`"
|
| 428 |
+
if reason:
|
| 429 |
+
gb_msg += f"\n**Reason** : {reason}"
|
| 430 |
+
await xx.edit(gb_msg)
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
@ultroid_cmd(pattern="g(admin|)cast( (.*)|$)", fullsudo=True)
|
| 434 |
+
async def gcast(event):
|
| 435 |
+
text, btn, reply = "", None, None
|
| 436 |
+
if xx := event.pattern_match.group(2):
|
| 437 |
+
msg, btn = get_msg_button(event.text.split(maxsplit=1)[1])
|
| 438 |
+
elif event.is_reply:
|
| 439 |
+
reply = await event.get_reply_message()
|
| 440 |
+
msg = reply.text
|
| 441 |
+
if reply.buttons:
|
| 442 |
+
btn = format_btn(reply.buttons)
|
| 443 |
+
else:
|
| 444 |
+
msg, btn = get_msg_button(msg)
|
| 445 |
+
else:
|
| 446 |
+
return await eor(
|
| 447 |
+
event, "`Give some text to Globally Broadcast or reply a message..`"
|
| 448 |
+
)
|
| 449 |
+
|
| 450 |
+
kk = await event.eor("`Globally Broadcasting Msg...`")
|
| 451 |
+
er = 0
|
| 452 |
+
done = 0
|
| 453 |
+
err = ""
|
| 454 |
+
if event.client._dialogs:
|
| 455 |
+
dialog = event.client._dialogs
|
| 456 |
+
else:
|
| 457 |
+
dialog = await event.client.get_dialogs()
|
| 458 |
+
event.client._dialogs.extend(dialog)
|
| 459 |
+
for x in dialog:
|
| 460 |
+
if x.is_group:
|
| 461 |
+
chat = x.entity.id
|
| 462 |
+
if (
|
| 463 |
+
not keym.contains(chat)
|
| 464 |
+
and int(f"-100{str(chat)}") not in NOSPAM_CHAT
|
| 465 |
+
and (
|
| 466 |
+
(
|
| 467 |
+
event.text[2:7] != "admin"
|
| 468 |
+
or (x.entity.admin_rights or x.entity.creator)
|
| 469 |
+
)
|
| 470 |
+
)
|
| 471 |
+
):
|
| 472 |
+
try:
|
| 473 |
+
if btn:
|
| 474 |
+
bt = create_tl_btn(btn)
|
| 475 |
+
await something(
|
| 476 |
+
event,
|
| 477 |
+
msg,
|
| 478 |
+
reply.media if reply else None,
|
| 479 |
+
bt,
|
| 480 |
+
chat=chat,
|
| 481 |
+
reply=False,
|
| 482 |
+
)
|
| 483 |
+
else:
|
| 484 |
+
await event.client.send_message(
|
| 485 |
+
chat, msg, file=reply.media if reply else None
|
| 486 |
+
)
|
| 487 |
+
done += 1
|
| 488 |
+
except FloodWaitError as fw:
|
| 489 |
+
await asyncio.sleep(fw.seconds + 10)
|
| 490 |
+
try:
|
| 491 |
+
if btn:
|
| 492 |
+
bt = create_tl_btn(btn)
|
| 493 |
+
await something(
|
| 494 |
+
event,
|
| 495 |
+
msg,
|
| 496 |
+
reply.media if reply else None,
|
| 497 |
+
bt,
|
| 498 |
+
chat=chat,
|
| 499 |
+
reply=False,
|
| 500 |
+
)
|
| 501 |
+
else:
|
| 502 |
+
await event.client.send_message(
|
| 503 |
+
chat, msg, file=reply.media if reply else None
|
| 504 |
+
)
|
| 505 |
+
done += 1
|
| 506 |
+
except Exception as rr:
|
| 507 |
+
err += f"• {rr}\n"
|
| 508 |
+
er += 1
|
| 509 |
+
except BaseException as h:
|
| 510 |
+
err += f"• {str(h)}" + "\n"
|
| 511 |
+
er += 1
|
| 512 |
+
text += f"Done in {done} chats, error in {er} chat(s)"
|
| 513 |
+
if err != "":
|
| 514 |
+
open("gcast-error.log", "w+").write(err)
|
| 515 |
+
text += f"\nYou can do `{HNDLR}ul gcast-error.log` to know error report."
|
| 516 |
+
await kk.edit(text)
|
| 517 |
+
|
| 518 |
+
|
| 519 |
+
@ultroid_cmd(pattern="gucast( (.*)|$)", fullsudo=True)
|
| 520 |
+
async def gucast(event):
|
| 521 |
+
msg, btn, reply = "", None, None
|
| 522 |
+
if xx := event.pattern_match.group(1).strip():
|
| 523 |
+
msg, btn = get_msg_button(event.text.split(maxsplit=1)[1])
|
| 524 |
+
elif event.is_reply:
|
| 525 |
+
reply = await event.get_reply_message()
|
| 526 |
+
msg = reply.text
|
| 527 |
+
if reply.buttons:
|
| 528 |
+
btn = format_btn(reply.buttons)
|
| 529 |
+
else:
|
| 530 |
+
msg, btn = get_msg_button(msg)
|
| 531 |
+
else:
|
| 532 |
+
return await eor(
|
| 533 |
+
event, "`Give some text to Globally Broadcast or reply a message..`"
|
| 534 |
+
)
|
| 535 |
+
kk = await event.eor("`Globally Broadcasting Msg...`")
|
| 536 |
+
er = 0
|
| 537 |
+
done = 0
|
| 538 |
+
if event.client._dialogs:
|
| 539 |
+
dialog = event.client._dialogs
|
| 540 |
+
else:
|
| 541 |
+
dialog = await event.client.get_dialogs()
|
| 542 |
+
event.client._dialogs.extend(dialog)
|
| 543 |
+
for x in dialog:
|
| 544 |
+
if x.is_user and not x.entity.bot:
|
| 545 |
+
chat = x.id
|
| 546 |
+
if not keym.contains(chat):
|
| 547 |
+
try:
|
| 548 |
+
if btn:
|
| 549 |
+
bt = create_tl_btn(btn)
|
| 550 |
+
await something(
|
| 551 |
+
event,
|
| 552 |
+
msg,
|
| 553 |
+
reply.media if reply else None,
|
| 554 |
+
bt,
|
| 555 |
+
chat=chat,
|
| 556 |
+
reply=False,
|
| 557 |
+
)
|
| 558 |
+
else:
|
| 559 |
+
await event.client.send_message(
|
| 560 |
+
chat, msg, file=reply.media if reply else None
|
| 561 |
+
)
|
| 562 |
+
done += 1
|
| 563 |
+
except BaseException:
|
| 564 |
+
er += 1
|
| 565 |
+
await kk.edit(f"Done in {done} chats, error in {er} chat(s)")
|
| 566 |
+
|
| 567 |
+
|
| 568 |
+
@ultroid_cmd(pattern="gkick( (.*)|$)", fullsudo=True)
|
| 569 |
+
async def gkick(e):
|
| 570 |
+
xx = await e.eor("`Gkicking...`")
|
| 571 |
+
if e.reply_to_msg_id:
|
| 572 |
+
userid = (await e.get_reply_message()).sender_id
|
| 573 |
+
elif e.pattern_match.group(1).strip():
|
| 574 |
+
userid = await e.client.parse_id(e.pattern_match.group(1).strip())
|
| 575 |
+
elif e.is_private:
|
| 576 |
+
userid = e.chat_id
|
| 577 |
+
else:
|
| 578 |
+
return await xx.edit("`Reply to some msg or add their id.`", time=5)
|
| 579 |
+
name = (await e.client.get_entity(userid)).first_name
|
| 580 |
+
chats = 0
|
| 581 |
+
if userid == ultroid_bot.uid:
|
| 582 |
+
return await xx.eor("`I can't gkick myself.`", time=3)
|
| 583 |
+
if userid in DEVLIST:
|
| 584 |
+
return await xx.eor("`I can't gkick my Developers.`", time=3)
|
| 585 |
+
if e.client._dialogs:
|
| 586 |
+
dialog = e.client._dialogs
|
| 587 |
+
else:
|
| 588 |
+
dialog = await e.client.get_dialogs()
|
| 589 |
+
e.client._dialogs.extend(dialog)
|
| 590 |
+
for gkick in dialog:
|
| 591 |
+
if gkick.is_group or gkick.is_channel:
|
| 592 |
+
try:
|
| 593 |
+
await e.client.kick_participant(gkick.id, userid)
|
| 594 |
+
chats += 1
|
| 595 |
+
except BaseException:
|
| 596 |
+
pass
|
| 597 |
+
await xx.edit(f"`Gkicked` [{name}](tg://user?id={userid}) `in {chats} chats.`")
|
| 598 |
+
|
| 599 |
+
|
| 600 |
+
@ultroid_cmd(pattern="gmute( (.*)|$)", fullsudo=True)
|
| 601 |
+
async def _(e):
|
| 602 |
+
xx = await e.eor("`Gmuting...`")
|
| 603 |
+
if e.reply_to_msg_id:
|
| 604 |
+
userid = (await e.get_reply_message()).sender_id
|
| 605 |
+
elif e.pattern_match.group(1).strip():
|
| 606 |
+
userid = await e.client.parse_id(e.pattern_match.group(1).strip())
|
| 607 |
+
elif e.is_private:
|
| 608 |
+
userid = e.chat_id
|
| 609 |
+
else:
|
| 610 |
+
return await xx.eor("`Reply to some msg or add their id.`", tome=5, time=5)
|
| 611 |
+
name = await e.client.get_entity(userid)
|
| 612 |
+
chats = 0
|
| 613 |
+
if userid == ultroid_bot.uid:
|
| 614 |
+
return await xx.eor("`I can't gmute myself.`", time=3)
|
| 615 |
+
if userid in DEVLIST:
|
| 616 |
+
return await xx.eor("`I can't gmute my Developers.`", time=3)
|
| 617 |
+
if is_gmuted(userid):
|
| 618 |
+
return await xx.eor("`User is already gmuted.`", time=4)
|
| 619 |
+
if e.client._dialogs:
|
| 620 |
+
dialog = e.client._dialogs
|
| 621 |
+
else:
|
| 622 |
+
dialog = await e.client.get_dialogs()
|
| 623 |
+
e.client._dialogs.extend(dialog)
|
| 624 |
+
for onmute in dialog:
|
| 625 |
+
if onmute.is_group:
|
| 626 |
+
try:
|
| 627 |
+
await e.client.edit_permissions(onmute.id, userid, send_messages=False)
|
| 628 |
+
chats += 1
|
| 629 |
+
except BaseException:
|
| 630 |
+
pass
|
| 631 |
+
gmute(userid)
|
| 632 |
+
await xx.edit(f"`Gmuted` {inline_mention(name)} `in {chats} chats.`")
|
| 633 |
+
|
| 634 |
+
|
| 635 |
+
@ultroid_cmd(pattern="ungmute( (.*)|$)", fullsudo=True)
|
| 636 |
+
async def _(e):
|
| 637 |
+
xx = await e.eor("`UnGmuting...`")
|
| 638 |
+
if e.reply_to_msg_id:
|
| 639 |
+
userid = (await e.get_reply_message()).sender_id
|
| 640 |
+
elif e.pattern_match.group(1).strip():
|
| 641 |
+
userid = await e.client.parse_id(e.pattern_match.group(1).strip())
|
| 642 |
+
elif e.is_private:
|
| 643 |
+
userid = e.chat_id
|
| 644 |
+
else:
|
| 645 |
+
return await xx.eor("`Reply to some msg or add their id.`", time=5)
|
| 646 |
+
name = (await e.client.get_entity(userid)).first_name
|
| 647 |
+
chats = 0
|
| 648 |
+
if not is_gmuted(userid):
|
| 649 |
+
return await xx.eor("`User is not gmuted.`", time=3)
|
| 650 |
+
if e.client._dialogs:
|
| 651 |
+
dialog = e.client._dialogs
|
| 652 |
+
else:
|
| 653 |
+
dialog = await e.client.get_dialogs()
|
| 654 |
+
e.client._dialogs.extend(dialog)
|
| 655 |
+
for hurr in dialog:
|
| 656 |
+
if hurr.is_group:
|
| 657 |
+
try:
|
| 658 |
+
await e.client.edit_permissions(hurr.id, userid, send_messages=True)
|
| 659 |
+
chats += 1
|
| 660 |
+
except BaseException:
|
| 661 |
+
pass
|
| 662 |
+
ungmute(userid)
|
| 663 |
+
await xx.edit(f"`Ungmuted` {inline_mention(name)} `in {chats} chats.`")
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
@ultroid_cmd(
|
| 667 |
+
pattern="listgban$",
|
| 668 |
+
)
|
| 669 |
+
async def list_gengbanned(event):
|
| 670 |
+
users = list_gbanned()
|
| 671 |
+
x = await event.eor(get_string("com_1"))
|
| 672 |
+
msg = ""
|
| 673 |
+
if not users:
|
| 674 |
+
return await x.edit("`You haven't GBanned anyone!`")
|
| 675 |
+
for i in users:
|
| 676 |
+
try:
|
| 677 |
+
name = await event.client.get_entity(int(i))
|
| 678 |
+
except BaseException:
|
| 679 |
+
name = i
|
| 680 |
+
msg += f"<strong>User</strong>: {inline_mention(name, html=True)}\n"
|
| 681 |
+
reason = users[i]
|
| 682 |
+
msg += f"<strong>Reason</strong>: {reason}\n\n" if reason is not None else "\n"
|
| 683 |
+
gbanned_users = f"<strong>List of users GBanned by {OWNER_NAME}</strong>:\n\n{msg}"
|
| 684 |
+
if len(gbanned_users) > 4096:
|
| 685 |
+
with open("gbanned.txt", "w") as f:
|
| 686 |
+
f.write(
|
| 687 |
+
gbanned_users.replace("<strong>", "")
|
| 688 |
+
.replace("</strong>", "")
|
| 689 |
+
.replace("<a href=tg://user?id=", "")
|
| 690 |
+
.replace("</a>", "")
|
| 691 |
+
)
|
| 692 |
+
await x.reply(
|
| 693 |
+
file="gbanned.txt",
|
| 694 |
+
message=f"List of users GBanned by {inline_mention(ultroid_bot.me)}",
|
| 695 |
+
)
|
| 696 |
+
os.remove("gbanned.txt")
|
| 697 |
+
await x.delete()
|
| 698 |
+
else:
|
| 699 |
+
await x.edit(gbanned_users, parse_mode="html")
|
| 700 |
+
|
| 701 |
+
|
| 702 |
+
@ultroid_cmd(
|
| 703 |
+
pattern="gstat( (.*)|$)",
|
| 704 |
+
)
|
| 705 |
+
async def gstat_(e):
|
| 706 |
+
xx = await e.eor(get_string("com_1"))
|
| 707 |
+
if e.is_private:
|
| 708 |
+
userid = (await e.get_chat()).id
|
| 709 |
+
elif e.reply_to_msg_id:
|
| 710 |
+
userid = (await e.get_reply_message()).sender_id
|
| 711 |
+
elif e.pattern_match.group(1).strip():
|
| 712 |
+
try:
|
| 713 |
+
userid = await e.client.parse_id(e.pattern_match.group(1).strip())
|
| 714 |
+
except Exception as err:
|
| 715 |
+
return await xx.eor(f"{err}", time=10)
|
| 716 |
+
else:
|
| 717 |
+
return await xx.eor("`Reply to some msg or add their id.`", time=5)
|
| 718 |
+
name = (await e.client.get_entity(userid)).first_name
|
| 719 |
+
msg = f"**{name} is "
|
| 720 |
+
is_banned = is_gbanned(userid)
|
| 721 |
+
reason = list_gbanned().get(userid)
|
| 722 |
+
if is_banned:
|
| 723 |
+
msg += "Globally Banned"
|
| 724 |
+
msg += f" with reason** `{reason}`" if reason else ".**"
|
| 725 |
+
else:
|
| 726 |
+
msg += "not Globally Banned.**"
|
| 727 |
+
await xx.edit(msg)
|
| 728 |
+
|
| 729 |
+
|
| 730 |
+
@ultroid_cmd(pattern="gblacklist$")
|
| 731 |
+
async def blacklist_(event):
|
| 732 |
+
await gblacker(event, "add")
|
| 733 |
+
|
| 734 |
+
|
| 735 |
+
@ultroid_cmd(pattern="ungblacklist$")
|
| 736 |
+
async def ungblacker(event):
|
| 737 |
+
await gblacker(event, "remove")
|
| 738 |
+
|
| 739 |
+
|
| 740 |
+
async def gblacker(event, type_):
|
| 741 |
+
try:
|
| 742 |
+
chat_id = int(event.text.split(maxsplit=1)[1])
|
| 743 |
+
try:
|
| 744 |
+
chat_id = (await event.client.get_entity(chat_id)).id
|
| 745 |
+
except Exception as e:
|
| 746 |
+
return await event.eor(f"**ERROR**\n`{str(e)}`")
|
| 747 |
+
except IndexError:
|
| 748 |
+
chat_id = event.chat_id
|
| 749 |
+
if type_ == "add":
|
| 750 |
+
keym.add(chat_id)
|
| 751 |
+
elif type_ == "remove":
|
| 752 |
+
keym.remove(chat_id)
|
| 753 |
+
await event.eor(f"Global Broadcasts: \n{type_}ed {chat_id}")
|
plugins/greetings.py
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
---- Welcomes ----
|
| 11 |
+
• `{i}setwelcome <message/reply to message>`
|
| 12 |
+
Set welcome message in the current chat.
|
| 13 |
+
|
| 14 |
+
• `{i}clearwelcome`
|
| 15 |
+
Delete the welcome in the current chat.
|
| 16 |
+
|
| 17 |
+
• `{i}getwelcome`
|
| 18 |
+
Get the welcome message in the current chat.
|
| 19 |
+
|
| 20 |
+
---- GoodByes ----
|
| 21 |
+
• `{i}setgoodbye <message/reply to message>`
|
| 22 |
+
Set goodbye message in the current chat.
|
| 23 |
+
|
| 24 |
+
• `{i}cleargoodbye`
|
| 25 |
+
Delete the goodbye in the current chat.
|
| 26 |
+
|
| 27 |
+
• `{i}getgoodbye`
|
| 28 |
+
Get the goodbye message in the current chat.
|
| 29 |
+
|
| 30 |
+
• `{i}thankmembers on/off`
|
| 31 |
+
Send a thank you sticker on hitting a members count of 100*x in your groups.
|
| 32 |
+
"""
|
| 33 |
+
import os
|
| 34 |
+
|
| 35 |
+
from . import upload_file as uf
|
| 36 |
+
from telethon.utils import pack_bot_file_id
|
| 37 |
+
|
| 38 |
+
from pyUltroid.dB.greetings_db import (
|
| 39 |
+
add_goodbye,
|
| 40 |
+
add_thanks,
|
| 41 |
+
add_welcome,
|
| 42 |
+
delete_goodbye,
|
| 43 |
+
delete_welcome,
|
| 44 |
+
get_goodbye,
|
| 45 |
+
get_welcome,
|
| 46 |
+
must_thank,
|
| 47 |
+
remove_thanks,
|
| 48 |
+
)
|
| 49 |
+
from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button
|
| 50 |
+
|
| 51 |
+
from . import HNDLR, eor, get_string, mediainfo, ultroid_cmd
|
| 52 |
+
from ._inline import something
|
| 53 |
+
|
| 54 |
+
Note = "\n\nNote: `{mention}`, `{group}`, `{count}`, `{name}`, `{fullname}`, `{username}`, `{userid}` can be used as formatting parameters.\n\n"
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
@ultroid_cmd(pattern="setwelcome", groups_only=True)
|
| 58 |
+
async def setwel(event):
|
| 59 |
+
x = await event.eor(get_string("com_1"))
|
| 60 |
+
r = await event.get_reply_message()
|
| 61 |
+
btn = format_btn(r.buttons) if (r and r.buttons) else None
|
| 62 |
+
try:
|
| 63 |
+
text = event.text.split(maxsplit=1)[1]
|
| 64 |
+
except IndexError:
|
| 65 |
+
text = r.text if r else None
|
| 66 |
+
if r and r.media:
|
| 67 |
+
wut = mediainfo(r.media)
|
| 68 |
+
if wut.startswith(("pic", "gif")):
|
| 69 |
+
dl = await r.download_media()
|
| 70 |
+
m = uf(dl)
|
| 71 |
+
os.remove(dl)
|
| 72 |
+
elif wut == "video":
|
| 73 |
+
if r.media.document.size > 8 * 1000 * 1000:
|
| 74 |
+
return await eor(x, get_string("com_4"), time=5)
|
| 75 |
+
dl = await r.download_media()
|
| 76 |
+
m = uf(dl)
|
| 77 |
+
os.remove(dl)
|
| 78 |
+
elif wut == "web":
|
| 79 |
+
m = None
|
| 80 |
+
else:
|
| 81 |
+
m = pack_bot_file_id(r.media)
|
| 82 |
+
if r.text:
|
| 83 |
+
txt = r.text
|
| 84 |
+
if not btn:
|
| 85 |
+
txt, btn = get_msg_button(r.text)
|
| 86 |
+
add_welcome(event.chat_id, txt, m, btn)
|
| 87 |
+
else:
|
| 88 |
+
add_welcome(event.chat_id, None, m, btn)
|
| 89 |
+
await eor(x, get_string("grt_1"))
|
| 90 |
+
elif text:
|
| 91 |
+
if not btn:
|
| 92 |
+
txt, btn = get_msg_button(text)
|
| 93 |
+
add_welcome(event.chat_id, txt, None, btn)
|
| 94 |
+
await eor(x, get_string("grt_1"))
|
| 95 |
+
else:
|
| 96 |
+
await eor(x, get_string("grt_3"), time=5)
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@ultroid_cmd(pattern="clearwelcome$", groups_only=True)
|
| 100 |
+
async def clearwel(event):
|
| 101 |
+
if not get_welcome(event.chat_id):
|
| 102 |
+
return await event.eor(get_string("grt_4"), time=5)
|
| 103 |
+
delete_welcome(event.chat_id)
|
| 104 |
+
await event.eor(get_string("grt_5"), time=5)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
@ultroid_cmd(pattern="getwelcome$", groups_only=True)
|
| 108 |
+
async def listwel(event):
|
| 109 |
+
wel = get_welcome(event.chat_id)
|
| 110 |
+
if not wel:
|
| 111 |
+
return await event.eor(get_string("grt_4"), time=5)
|
| 112 |
+
msgg, med = wel["welcome"], wel["media"]
|
| 113 |
+
if wel.get("button"):
|
| 114 |
+
btn = create_tl_btn(wel["button"])
|
| 115 |
+
return await something(event, msgg, med, btn)
|
| 116 |
+
await event.reply(f"**Welcome Note in this chat**\n\n`{msgg}`", file=med)
|
| 117 |
+
await event.delete()
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
@ultroid_cmd(pattern="setgoodbye", groups_only=True)
|
| 121 |
+
async def setgb(event):
|
| 122 |
+
x = await event.eor(get_string("com_1"))
|
| 123 |
+
r = await event.get_reply_message()
|
| 124 |
+
btn = format_btn(r.buttons) if (r and r.buttons) else None
|
| 125 |
+
try:
|
| 126 |
+
text = event.text.split(maxsplit=1)[1]
|
| 127 |
+
except IndexError:
|
| 128 |
+
text = r.text if r else None
|
| 129 |
+
if r and r.media:
|
| 130 |
+
wut = mediainfo(r.media)
|
| 131 |
+
if wut.startswith(("pic", "gif")):
|
| 132 |
+
dl = await r.download_media()
|
| 133 |
+
m = uf(dl)
|
| 134 |
+
os.remove(dl)
|
| 135 |
+
elif wut == "video":
|
| 136 |
+
if r.media.document.size > 8 * 1000 * 1000:
|
| 137 |
+
return await eor(x, get_string("com_4"), time=5)
|
| 138 |
+
dl = await r.download_media()
|
| 139 |
+
m = uf(dl)
|
| 140 |
+
os.remove(dl)
|
| 141 |
+
elif wut == "web":
|
| 142 |
+
m = None
|
| 143 |
+
else:
|
| 144 |
+
m = pack_bot_file_id(r.media)
|
| 145 |
+
if r.text:
|
| 146 |
+
txt = r.text
|
| 147 |
+
if not btn:
|
| 148 |
+
txt, btn = get_msg_button(r.text)
|
| 149 |
+
add_goodbye(event.chat_id, txt, m, btn)
|
| 150 |
+
else:
|
| 151 |
+
add_goodbye(event.chat_id, None, m, btn)
|
| 152 |
+
await eor(x, "`Goodbye note saved`")
|
| 153 |
+
elif text:
|
| 154 |
+
if not btn:
|
| 155 |
+
txt, btn = get_msg_button(text)
|
| 156 |
+
add_goodbye(event.chat_id, txt, None, btn)
|
| 157 |
+
await eor(x, "`Goodbye note saved`")
|
| 158 |
+
else:
|
| 159 |
+
await eor(x, get_string("grt_7"), time=5)
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
@ultroid_cmd(pattern="cleargoodbye$", groups_only=True)
|
| 163 |
+
async def clearwgb(event):
|
| 164 |
+
if not get_goodbye(event.chat_id):
|
| 165 |
+
return await event.eor(get_string("grt_6"), time=5)
|
| 166 |
+
delete_goodbye(event.chat_id)
|
| 167 |
+
await event.eor("`Goodbye Note Deleted`", time=5)
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
@ultroid_cmd(pattern="getgoodbye$", groups_only=True)
|
| 171 |
+
async def listgd(event):
|
| 172 |
+
wel = get_goodbye(event.chat_id)
|
| 173 |
+
if not wel:
|
| 174 |
+
return await event.eor(get_string("grt_6"), time=5)
|
| 175 |
+
msgg = wel["goodbye"]
|
| 176 |
+
med = wel["media"]
|
| 177 |
+
if wel.get("button"):
|
| 178 |
+
btn = create_tl_btn(wel["button"])
|
| 179 |
+
return await something(event, msgg, med, btn)
|
| 180 |
+
await event.reply(f"**Goodbye Note in this chat**\n\n`{msgg}`", file=med)
|
| 181 |
+
await event.delete()
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
@ultroid_cmd(pattern="thankmembers (on|off)", groups_only=True)
|
| 185 |
+
async def thank_set(event):
|
| 186 |
+
type_ = event.pattern_match.group(1).strip()
|
| 187 |
+
if not type_ or type_ == "":
|
| 188 |
+
await eor(
|
| 189 |
+
event,
|
| 190 |
+
f"**Current Chat Settings:**\n**Thanking Members:** `{must_thank(event.chat_id)}`\n\nUse `{HNDLR}thankmembers on` or `{HNDLR}thankmembers off` to toggle current settings!",
|
| 191 |
+
)
|
| 192 |
+
return
|
| 193 |
+
chat = event.chat_id
|
| 194 |
+
if type_.lower() == "on":
|
| 195 |
+
add_thanks(chat)
|
| 196 |
+
elif type_.lower() == "off":
|
| 197 |
+
remove_thanks(chat)
|
| 198 |
+
await eor(
|
| 199 |
+
event,
|
| 200 |
+
f"**Done! Thank you members has been turned** `{type_.lower()}` **for this chat**!",
|
| 201 |
+
)
|
plugins/imagetools.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}border <reply to photo/sticker>`
|
| 11 |
+
To create border around that media..
|
| 12 |
+
Ex - `{i}border 12,22,23`
|
| 13 |
+
- `{i}border 12,22,23 ; width (in number)`
|
| 14 |
+
|
| 15 |
+
• `{i}grey <reply to any media>`
|
| 16 |
+
To make it black nd white.
|
| 17 |
+
|
| 18 |
+
• `{i}color <reply to any Black nd White media>`
|
| 19 |
+
To make it Colorfull.
|
| 20 |
+
|
| 21 |
+
• `{i}toon <reply to any media>`
|
| 22 |
+
To make it toon.
|
| 23 |
+
|
| 24 |
+
• `{i}danger <reply to any media>`
|
| 25 |
+
To make it look Danger.
|
| 26 |
+
|
| 27 |
+
• `{i}negative <reply to any media>`
|
| 28 |
+
To make negative image.
|
| 29 |
+
|
| 30 |
+
• `{i}blur <reply to any media>`
|
| 31 |
+
To make it blurry.
|
| 32 |
+
|
| 33 |
+
• `{i}quad <reply to any media>`
|
| 34 |
+
create a Vortex.
|
| 35 |
+
|
| 36 |
+
• `{i}mirror <reply to any media>`
|
| 37 |
+
To create mirror pic.
|
| 38 |
+
|
| 39 |
+
• `{i}flip <reply to any media>`
|
| 40 |
+
To make it flip.
|
| 41 |
+
|
| 42 |
+
• `{i}sketch <reply to any media>`
|
| 43 |
+
To draw its sketch.
|
| 44 |
+
|
| 45 |
+
• `{i}blue <reply to any media>`
|
| 46 |
+
just cool.
|
| 47 |
+
|
| 48 |
+
• `{i}csample <color name /color code>`
|
| 49 |
+
example : `{i}csample red`
|
| 50 |
+
`{i}csample #ffffff`
|
| 51 |
+
|
| 52 |
+
• `{i}pixelator <reply image>`
|
| 53 |
+
Create a Pixelated Image..
|
| 54 |
+
"""
|
| 55 |
+
import os
|
| 56 |
+
|
| 57 |
+
from . import LOGS, con
|
| 58 |
+
|
| 59 |
+
try:
|
| 60 |
+
import cv2
|
| 61 |
+
except ImportError:
|
| 62 |
+
LOGS.error(f"{__file__}: OpenCv not Installed.")
|
| 63 |
+
|
| 64 |
+
import numpy as np
|
| 65 |
+
|
| 66 |
+
try:
|
| 67 |
+
from PIL import Image
|
| 68 |
+
except ImportError:
|
| 69 |
+
Image = None
|
| 70 |
+
LOGS.info(f"{__file__}: PIL not Installed.")
|
| 71 |
+
|
| 72 |
+
from . import upload_file as upf
|
| 73 |
+
from telethon.errors.rpcerrorlist import (
|
| 74 |
+
ChatSendMediaForbiddenError,
|
| 75 |
+
MessageDeleteForbiddenError,
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
from . import (
|
| 79 |
+
Redis,
|
| 80 |
+
async_searcher,
|
| 81 |
+
download_file,
|
| 82 |
+
get_string,
|
| 83 |
+
requests,
|
| 84 |
+
udB,
|
| 85 |
+
ultroid_cmd,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
@ultroid_cmd(pattern="color$")
|
| 90 |
+
async def _(event):
|
| 91 |
+
reply = await event.get_reply_message()
|
| 92 |
+
if not (reply and reply.media):
|
| 93 |
+
return await event.eor("`Reply To a Black and White Image`")
|
| 94 |
+
xx = await event.eor("`Coloring image 🎨🖌️...`")
|
| 95 |
+
image = await reply.download_media()
|
| 96 |
+
img = cv2.VideoCapture(image)
|
| 97 |
+
ret, frame = img.read()
|
| 98 |
+
cv2.imwrite("ult.jpg", frame)
|
| 99 |
+
if udB.get_key("DEEP_API"):
|
| 100 |
+
key = Redis("DEEP_API")
|
| 101 |
+
else:
|
| 102 |
+
key = "quickstart-QUdJIGlzIGNvbWluZy4uLi4K"
|
| 103 |
+
r = requests.post(
|
| 104 |
+
"https://api.deepai.org/api/colorizer",
|
| 105 |
+
files={"image": open("ult.jpg", "rb")},
|
| 106 |
+
headers={"api-key": key},
|
| 107 |
+
)
|
| 108 |
+
os.remove("ult.jpg")
|
| 109 |
+
os.remove(image)
|
| 110 |
+
if "status" in r.json():
|
| 111 |
+
return await event.edit(
|
| 112 |
+
r.json()["status"] + "\nGet api nd set `{i}setdb DEEP_API key`"
|
| 113 |
+
)
|
| 114 |
+
r_json = r.json()["output_url"]
|
| 115 |
+
await event.client.send_file(event.chat_id, r_json, reply_to=reply)
|
| 116 |
+
await xx.delete()
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
@ultroid_cmd(pattern="(grey|blur|negative|danger|mirror|quad|sketch|flip|toon)$")
|
| 120 |
+
async def ult_tools(event):
|
| 121 |
+
match = event.pattern_match.group(1)
|
| 122 |
+
ureply = await event.get_reply_message()
|
| 123 |
+
if not (ureply and (ureply.media)):
|
| 124 |
+
await event.eor(get_string("cvt_3"))
|
| 125 |
+
return
|
| 126 |
+
ultt = await ureply.download_media()
|
| 127 |
+
xx = await event.eor(get_string("com_1"))
|
| 128 |
+
if ultt.endswith(".tgs"):
|
| 129 |
+
xx = await xx.edit(get_string("sts_9"))
|
| 130 |
+
file = await con.convert(ultt, convert_to="png", outname="ult")
|
| 131 |
+
ult = cv2.imread(file)
|
| 132 |
+
if match == "grey":
|
| 133 |
+
ultroid = cv2.cvtColor(ult, cv2.COLOR_BGR2GRAY)
|
| 134 |
+
elif match == "blur":
|
| 135 |
+
ultroid = cv2.GaussianBlur(ult, (35, 35), 0)
|
| 136 |
+
elif match == "negative":
|
| 137 |
+
ultroid = cv2.bitwise_not(ult)
|
| 138 |
+
elif match == "danger":
|
| 139 |
+
dan = cv2.cvtColor(ult, cv2.COLOR_BGR2RGB)
|
| 140 |
+
ultroid = cv2.cvtColor(dan, cv2.COLOR_HSV2BGR)
|
| 141 |
+
elif match == "mirror":
|
| 142 |
+
ish = cv2.flip(ult, 1)
|
| 143 |
+
ultroid = cv2.hconcat([ult, ish])
|
| 144 |
+
elif match == "flip":
|
| 145 |
+
trn = cv2.flip(ult, 1)
|
| 146 |
+
ish = cv2.rotate(trn, cv2.ROTATE_180)
|
| 147 |
+
ultroid = cv2.vconcat([ult, ish])
|
| 148 |
+
elif match == "quad":
|
| 149 |
+
ult = cv2.imread(file)
|
| 150 |
+
roid = cv2.flip(ult, 1)
|
| 151 |
+
mici = cv2.hconcat([ult, roid])
|
| 152 |
+
fr = cv2.flip(mici, 1)
|
| 153 |
+
trn = cv2.rotate(fr, cv2.ROTATE_180)
|
| 154 |
+
ultroid = cv2.vconcat([mici, trn])
|
| 155 |
+
elif match == "sketch":
|
| 156 |
+
gray_image = cv2.cvtColor(ult, cv2.COLOR_BGR2GRAY)
|
| 157 |
+
inverted_gray_image = 255 - gray_image
|
| 158 |
+
blurred_img = cv2.GaussianBlur(inverted_gray_image, (21, 21), 0)
|
| 159 |
+
inverted_blurred_img = 255 - blurred_img
|
| 160 |
+
ultroid = cv2.divide(gray_image, inverted_blurred_img, scale=256.0)
|
| 161 |
+
elif match == "toon":
|
| 162 |
+
height, width, _ = ult.shape
|
| 163 |
+
samples = np.zeros([height * width, 3], dtype=np.float32)
|
| 164 |
+
count = 0
|
| 165 |
+
for x in range(height):
|
| 166 |
+
for y in range(width):
|
| 167 |
+
samples[count] = ult[x][y]
|
| 168 |
+
count += 1
|
| 169 |
+
_, labels, centers = cv2.kmeans(
|
| 170 |
+
samples,
|
| 171 |
+
12,
|
| 172 |
+
None,
|
| 173 |
+
(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10000, 0.0001),
|
| 174 |
+
5,
|
| 175 |
+
cv2.KMEANS_PP_CENTERS,
|
| 176 |
+
)
|
| 177 |
+
centers = np.uint8(centers)
|
| 178 |
+
ish = centers[labels.flatten()]
|
| 179 |
+
ultroid = ish.reshape(ult.shape)
|
| 180 |
+
cv2.imwrite("ult.jpg", ultroid)
|
| 181 |
+
await ureply.reply(
|
| 182 |
+
file="ult.jpg",
|
| 183 |
+
force_document=False,
|
| 184 |
+
)
|
| 185 |
+
await xx.delete()
|
| 186 |
+
os.remove("ult.jpg")
|
| 187 |
+
os.remove(file)
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
@ultroid_cmd(pattern="csample (.*)")
|
| 191 |
+
async def sampl(ult):
|
| 192 |
+
if color := ult.pattern_match.group(1).strip():
|
| 193 |
+
img = Image.new("RGB", (200, 100), f"{color}")
|
| 194 |
+
img.save("csample.png")
|
| 195 |
+
try:
|
| 196 |
+
try:
|
| 197 |
+
await ult.delete()
|
| 198 |
+
await ult.respond(f"Colour Sample for `{color}` !", file="csample.png")
|
| 199 |
+
except MessageDeleteForbiddenError:
|
| 200 |
+
await ult.reply(f"Colour Sample for `{color}` !", file="csample.png")
|
| 201 |
+
except ChatSendMediaForbiddenError:
|
| 202 |
+
await ult.eor("Umm! Sending Media is disabled here!")
|
| 203 |
+
|
| 204 |
+
else:
|
| 205 |
+
await ult.eor("Wrong Color Name/Hex Code specified!")
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
@ultroid_cmd(
|
| 209 |
+
pattern="blue$",
|
| 210 |
+
)
|
| 211 |
+
async def ultd(event):
|
| 212 |
+
ureply = await event.get_reply_message()
|
| 213 |
+
xx = await event.eor("`...`")
|
| 214 |
+
if not (ureply and (ureply.media)):
|
| 215 |
+
await xx.edit(get_string("cvt_3"))
|
| 216 |
+
return
|
| 217 |
+
ultt = await ureply.download_media()
|
| 218 |
+
if ultt.endswith(".tgs"):
|
| 219 |
+
await xx.edit(get_string("sts_9"))
|
| 220 |
+
file = await con.convert(ultt, convert_to="png", outname="ult")
|
| 221 |
+
lnk = upf(file)
|
| 222 |
+
r = await async_searcher(
|
| 223 |
+
f"https://nekobot.xyz/api/imagegen?type=blurpify&image={lnk}", re_json=True
|
| 224 |
+
)
|
| 225 |
+
ms = r.get("message")
|
| 226 |
+
if not r["success"]:
|
| 227 |
+
return await xx.edit(ms)
|
| 228 |
+
await download_file(ms, "ult.png")
|
| 229 |
+
img = Image.open("ult.png").convert("RGB")
|
| 230 |
+
img.save("ult.webp", "webp")
|
| 231 |
+
await event.client.send_file(
|
| 232 |
+
event.chat_id,
|
| 233 |
+
"ult.webp",
|
| 234 |
+
force_document=False,
|
| 235 |
+
reply_to=event.reply_to_msg_id,
|
| 236 |
+
)
|
| 237 |
+
await xx.delete()
|
| 238 |
+
os.remove("ult.png")
|
| 239 |
+
os.remove("ult.webp")
|
| 240 |
+
os.remove(ultt)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
@ultroid_cmd(pattern="border( (.*)|$)")
|
| 244 |
+
async def ok(event):
|
| 245 |
+
hm = await event.get_reply_message()
|
| 246 |
+
if not (hm and (hm.photo or hm.sticker)):
|
| 247 |
+
return await event.eor("`Reply to Sticker or Photo..`")
|
| 248 |
+
col = event.pattern_match.group(1).strip()
|
| 249 |
+
wh = 20
|
| 250 |
+
if not col:
|
| 251 |
+
col = [255, 255, 255]
|
| 252 |
+
else:
|
| 253 |
+
try:
|
| 254 |
+
if ";" in col:
|
| 255 |
+
col_ = col.split(";", maxsplit=1)
|
| 256 |
+
wh = int(col_[1])
|
| 257 |
+
col = col_[0]
|
| 258 |
+
col = [int(col) for col in col.split(",")[:2]]
|
| 259 |
+
except ValueError:
|
| 260 |
+
return await event.eor("`Not a Valid Input...`")
|
| 261 |
+
okla = await hm.download_media()
|
| 262 |
+
img1 = cv2.imread(okla)
|
| 263 |
+
constant = cv2.copyMakeBorder(img1, wh, wh, wh, wh, cv2.BORDER_CONSTANT, value=col)
|
| 264 |
+
cv2.imwrite("output.png", constant)
|
| 265 |
+
await event.client.send_file(event.chat.id, "output.png")
|
| 266 |
+
os.remove("output.png")
|
| 267 |
+
os.remove(okla)
|
| 268 |
+
await event.delete()
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
@ultroid_cmd(pattern="pixelator( (.*)|$)")
|
| 272 |
+
async def pixelator(event):
|
| 273 |
+
reply_message = await event.get_reply_message()
|
| 274 |
+
if not (reply_message and (reply_message.photo or reply_message.sticker)):
|
| 275 |
+
return await event.eor("`Reply to a photo`")
|
| 276 |
+
hw = 50
|
| 277 |
+
try:
|
| 278 |
+
hw = int(event.pattern_match.group(1).strip())
|
| 279 |
+
except (ValueError, TypeError):
|
| 280 |
+
pass
|
| 281 |
+
msg = await event.eor(get_string("com_1"))
|
| 282 |
+
image = await reply_message.download_media()
|
| 283 |
+
input_ = cv2.imread(image)
|
| 284 |
+
height, width = input_.shape[:2]
|
| 285 |
+
w, h = (hw, hw)
|
| 286 |
+
temp = cv2.resize(input_, (w, h), interpolation=cv2.INTER_LINEAR)
|
| 287 |
+
output = cv2.resize(temp, (width, height), interpolation=cv2.INTER_NEAREST)
|
| 288 |
+
cv2.imwrite("output.jpg", output)
|
| 289 |
+
await msg.respond("• Pixelated by Ultroid", file="output.jpg")
|
| 290 |
+
await msg.delete()
|
| 291 |
+
os.remove("output.jpg")
|
| 292 |
+
os.remove(image)
|
plugins/locks.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}lock <msgs/media/sticker/gif/games/inline/polls/invites/pin/changeinfo>`
|
| 11 |
+
Lock the Used Setting in Used Group.
|
| 12 |
+
|
| 13 |
+
• `{i}unlock <msgs/media/sticker/gif/games/inline/polls/invites/pin/changeinfo>`
|
| 14 |
+
UNLOCK the Used Setting in Used Group.
|
| 15 |
+
"""
|
| 16 |
+
from telethon.tl.functions.messages import EditChatDefaultBannedRightsRequest
|
| 17 |
+
|
| 18 |
+
from pyUltroid.fns.admins import lock_unlock
|
| 19 |
+
|
| 20 |
+
from . import ultroid_cmd
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@ultroid_cmd(
|
| 24 |
+
pattern="(un|)lock( (.*)|$)", admins_only=True, manager=True, require="change_info"
|
| 25 |
+
)
|
| 26 |
+
async def un_lock(e):
|
| 27 |
+
mat = e.pattern_match.group(2).strip()
|
| 28 |
+
if not mat:
|
| 29 |
+
return await e.eor("`Give some Proper Input..`", time=5)
|
| 30 |
+
lock = e.pattern_match.group(1) == ""
|
| 31 |
+
ml = lock_unlock(mat, lock)
|
| 32 |
+
if not ml:
|
| 33 |
+
return await e.eor("`Incorrect Input`", time=5)
|
| 34 |
+
msg = "Locked" if lock else "Unlocked"
|
| 35 |
+
try:
|
| 36 |
+
await e.client(EditChatDefaultBannedRightsRequest(e.chat_id, ml))
|
| 37 |
+
except Exception as er:
|
| 38 |
+
return await e.eor(str(er))
|
| 39 |
+
await e.eor(f"**{msg}** - `{mat}` ! ")
|
plugins/logo.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}logo <text>`
|
| 11 |
+
Generate a logo of the given Text
|
| 12 |
+
Or Reply To image , to write ur text on it.
|
| 13 |
+
Or Reply To Font File, To write with that font.
|
| 14 |
+
|
| 15 |
+
"""
|
| 16 |
+
import glob
|
| 17 |
+
import os
|
| 18 |
+
import random
|
| 19 |
+
|
| 20 |
+
from telethon.tl.types import InputMessagesFilterPhotos
|
| 21 |
+
|
| 22 |
+
try:
|
| 23 |
+
from PIL import Image
|
| 24 |
+
except ImportError:
|
| 25 |
+
Image = None
|
| 26 |
+
from pyUltroid.fns.misc import unsplashsearch
|
| 27 |
+
from pyUltroid.fns.tools import LogoHelper
|
| 28 |
+
|
| 29 |
+
from . import OWNER_ID, OWNER_NAME, download_file, get_string, mediainfo, ultroid_cmd
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
@ultroid_cmd(pattern="logo( (.*)|$)")
|
| 33 |
+
async def logo_gen(event):
|
| 34 |
+
xx = await event.eor(get_string("com_1"))
|
| 35 |
+
name = event.pattern_match.group(1).strip()
|
| 36 |
+
if not name:
|
| 37 |
+
return await xx.eor("`Give a name too!`", time=5)
|
| 38 |
+
bg_, font_ = None, None
|
| 39 |
+
if event.reply_to_msg_id:
|
| 40 |
+
temp = await event.get_reply_message()
|
| 41 |
+
if temp.media:
|
| 42 |
+
if hasattr(temp.media, "document") and (
|
| 43 |
+
("font" in temp.file.mime_type)
|
| 44 |
+
or (".ttf" in temp.file.name)
|
| 45 |
+
or (".otf" in temp.file.name)
|
| 46 |
+
):
|
| 47 |
+
font_ = await temp.download_media("resources/fonts/")
|
| 48 |
+
elif "pic" in mediainfo(temp.media):
|
| 49 |
+
bg_ = await temp.download_media()
|
| 50 |
+
if not bg_:
|
| 51 |
+
SRCH = [
|
| 52 |
+
"background",
|
| 53 |
+
"neon",
|
| 54 |
+
"anime",
|
| 55 |
+
"art",
|
| 56 |
+
"bridges",
|
| 57 |
+
"streets",
|
| 58 |
+
"computer",
|
| 59 |
+
"cyberpunk",
|
| 60 |
+
"nature",
|
| 61 |
+
"abstract",
|
| 62 |
+
"exoplanet",
|
| 63 |
+
"magic",
|
| 64 |
+
"3d render",
|
| 65 |
+
]
|
| 66 |
+
res = await unsplashsearch(random.choice(SRCH), limit=1)
|
| 67 |
+
bg_, _ = await download_file(res[0], "resources/downloads/logo.png")
|
| 68 |
+
newimg = "resources/downloads/unsplash-temp.jpg"
|
| 69 |
+
img_ = Image.open(bg_)
|
| 70 |
+
img_.save(newimg)
|
| 71 |
+
os.remove(bg_)
|
| 72 |
+
bg_ = newimg
|
| 73 |
+
|
| 74 |
+
if not font_:
|
| 75 |
+
fpath_ = glob.glob("resources/fonts/*")
|
| 76 |
+
font_ = random.choice(fpath_)
|
| 77 |
+
if len(name) <= 8:
|
| 78 |
+
strke = 10
|
| 79 |
+
elif len(name) >= 9:
|
| 80 |
+
strke = 5
|
| 81 |
+
else:
|
| 82 |
+
strke = 20
|
| 83 |
+
name = LogoHelper.make_logo(
|
| 84 |
+
bg_,
|
| 85 |
+
name,
|
| 86 |
+
font_,
|
| 87 |
+
fill="white",
|
| 88 |
+
stroke_width=strke,
|
| 89 |
+
stroke_fill="black",
|
| 90 |
+
)
|
| 91 |
+
await xx.edit("`Done!`")
|
| 92 |
+
await event.client.send_file(
|
| 93 |
+
event.chat_id,
|
| 94 |
+
file=name,
|
| 95 |
+
caption=f"Logo by [{OWNER_NAME}](tg://user?id={OWNER_ID})",
|
| 96 |
+
force_document=True,
|
| 97 |
+
)
|
| 98 |
+
os.remove(name)
|
| 99 |
+
await xx.delete()
|
| 100 |
+
if os.path.exists(bg_):
|
| 101 |
+
os.remove(bg_)
|
plugins/mediatools.py
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}mediainfo <reply to media>/<file path>/<url>`
|
| 11 |
+
To get info about it.
|
| 12 |
+
|
| 13 |
+
• `{i}rotate <degree/angle> <reply to media>`
|
| 14 |
+
Rotate any video/photo/media..
|
| 15 |
+
Note : for video it should be angle of 90's
|
| 16 |
+
"""
|
| 17 |
+
import os
|
| 18 |
+
import time
|
| 19 |
+
from datetime import datetime as dt
|
| 20 |
+
|
| 21 |
+
from pyUltroid.fns.misc import rotate_image
|
| 22 |
+
from pyUltroid.fns.tools import make_html_telegraph
|
| 23 |
+
|
| 24 |
+
from . import (
|
| 25 |
+
LOGS,
|
| 26 |
+
Telegraph,
|
| 27 |
+
bash,
|
| 28 |
+
downloader,
|
| 29 |
+
get_string,
|
| 30 |
+
upload_file,
|
| 31 |
+
is_url_ok,
|
| 32 |
+
mediainfo,
|
| 33 |
+
ultroid_cmd,
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
try:
|
| 37 |
+
import cv2
|
| 38 |
+
except ImportError:
|
| 39 |
+
LOGS.info("WARNING: 'cv2' not found!")
|
| 40 |
+
cv2 = None
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@ultroid_cmd(pattern="mediainfo( (.*)|$)")
|
| 44 |
+
async def mi(e):
|
| 45 |
+
r = await e.get_reply_message()
|
| 46 |
+
match = e.pattern_match.group(1).strip()
|
| 47 |
+
taime = time.time()
|
| 48 |
+
extra = ""
|
| 49 |
+
if r and r.media:
|
| 50 |
+
xx = mediainfo(r.media)
|
| 51 |
+
murl = r.media.stringify()
|
| 52 |
+
url = await make_html_telegraph("Mediainfo", f"<pre>{murl}</pre>")
|
| 53 |
+
extra = f"**[{xx}]({url})**\n\n"
|
| 54 |
+
e = await e.eor(f"{extra}`Loading More...`", link_preview=False)
|
| 55 |
+
|
| 56 |
+
if hasattr(r.media, "document"):
|
| 57 |
+
file = r.media.document
|
| 58 |
+
mime_type = file.mime_type
|
| 59 |
+
filename = r.file.name
|
| 60 |
+
if not filename:
|
| 61 |
+
if "audio" in mime_type:
|
| 62 |
+
filename = "audio_" + dt.now().isoformat("_", "seconds") + ".ogg"
|
| 63 |
+
elif "video" in mime_type:
|
| 64 |
+
filename = "video_" + dt.now().isoformat("_", "seconds") + ".mp4"
|
| 65 |
+
dl = await downloader(
|
| 66 |
+
f"resources/downloads/{filename}",
|
| 67 |
+
file,
|
| 68 |
+
e,
|
| 69 |
+
taime,
|
| 70 |
+
f"{extra}`Loading More...`",
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
naam = dl.name
|
| 74 |
+
else:
|
| 75 |
+
naam = await r.download_media()
|
| 76 |
+
elif match and (
|
| 77 |
+
os.path.isfile(match)
|
| 78 |
+
or (match.startswith("https://") and (await is_url_ok(match)))
|
| 79 |
+
):
|
| 80 |
+
naam, xx = match, "file"
|
| 81 |
+
else:
|
| 82 |
+
return await e.eor(get_string("cvt_3"), time=5)
|
| 83 |
+
out, er = await bash(f"mediainfo '{naam}'")
|
| 84 |
+
if er:
|
| 85 |
+
LOGS.info(er)
|
| 86 |
+
out = extra or str(er)
|
| 87 |
+
return await e.edit(out, link_preview=False)
|
| 88 |
+
makehtml = ""
|
| 89 |
+
if naam.endswith((".jpg", ".png")):
|
| 90 |
+
if os.path.exists(naam):
|
| 91 |
+
med = upload_file(naam)
|
| 92 |
+
else:
|
| 93 |
+
med = match
|
| 94 |
+
makehtml += f"<img src='{med}'><br>"
|
| 95 |
+
for line in out.split("\n"):
|
| 96 |
+
line = line.strip()
|
| 97 |
+
if not line:
|
| 98 |
+
makehtml += "<br>"
|
| 99 |
+
elif ":" not in line:
|
| 100 |
+
makehtml += f"<h3>{line}</h3>"
|
| 101 |
+
else:
|
| 102 |
+
makehtml += f"<p>{line}</p>"
|
| 103 |
+
try:
|
| 104 |
+
urll = await make_html_telegraph("Mediainfo", makehtml)
|
| 105 |
+
except Exception as er:
|
| 106 |
+
LOGS.exception(er)
|
| 107 |
+
return
|
| 108 |
+
await e.eor(f"{extra}[{get_string('mdi_1')}]({urll})", link_preview=False)
|
| 109 |
+
if not match:
|
| 110 |
+
os.remove(naam)
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
@ultroid_cmd(pattern="rotate( (.*)|$)")
|
| 114 |
+
async def rotate_(ult):
|
| 115 |
+
match = ult.pattern_match.group(1).strip()
|
| 116 |
+
if not ult.is_reply:
|
| 117 |
+
return await ult.eor("`Reply to a media...`")
|
| 118 |
+
if match:
|
| 119 |
+
try:
|
| 120 |
+
match = int(match)
|
| 121 |
+
except ValueError:
|
| 122 |
+
match = None
|
| 123 |
+
if not match:
|
| 124 |
+
return await ult.eor("`Please provide a valid angle to rotate media..`")
|
| 125 |
+
reply = await ult.get_reply_message()
|
| 126 |
+
msg = await ult.eor(get_string("com_1"))
|
| 127 |
+
photo = reply.game.photo if reply.game else None
|
| 128 |
+
if reply.video:
|
| 129 |
+
media = await reply.download_media()
|
| 130 |
+
file = f"{media}.mp4"
|
| 131 |
+
await bash(
|
| 132 |
+
f'ffmpeg -i "{media}" -c copy -metadata:s:v:0 rotate={match} "{file}" -y'
|
| 133 |
+
)
|
| 134 |
+
elif photo or reply.photo or reply.sticker:
|
| 135 |
+
media = await ult.client.download_media(photo or reply)
|
| 136 |
+
img = cv2.imread(media)
|
| 137 |
+
new_ = rotate_image(img, match)
|
| 138 |
+
file = "ult.png"
|
| 139 |
+
cv2.imwrite(file, new_)
|
| 140 |
+
else:
|
| 141 |
+
return await msg.edit("`Unsupported Media..\nReply to Photo/Video`")
|
| 142 |
+
if os.path.exists(file):
|
| 143 |
+
await ult.client.send_file(
|
| 144 |
+
ult.chat_id, file=file, video_note=bool(reply.video_note), reply_to=reply.id
|
| 145 |
+
)
|
| 146 |
+
os.remove(media)
|
| 147 |
+
await msg.try_delete()
|
plugins/misc.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
#
|
| 3 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 4 |
+
# PLease read the GNU Affero General Public License in
|
| 5 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 6 |
+
"""
|
| 7 |
+
✘ Commands Available -
|
| 8 |
+
|
| 9 |
+
• `{i}eod`
|
| 10 |
+
`Get Event of the Today`
|
| 11 |
+
|
| 12 |
+
• `{i}pntrst <link/id>`
|
| 13 |
+
Download and send pinterest pins
|
| 14 |
+
|
| 15 |
+
• `{i}gadget <search query>`
|
| 16 |
+
Gadget Search from Telegram.
|
| 17 |
+
|
| 18 |
+
• `{i}randomuser`
|
| 19 |
+
Generate details about a random user.
|
| 20 |
+
|
| 21 |
+
• `{i}ascii <reply image>`
|
| 22 |
+
Convert replied image into html.
|
| 23 |
+
"""
|
| 24 |
+
|
| 25 |
+
import os
|
| 26 |
+
from datetime import datetime as dt
|
| 27 |
+
|
| 28 |
+
from bs4 import BeautifulSoup as bs
|
| 29 |
+
|
| 30 |
+
try:
|
| 31 |
+
from htmlwebshot import WebShot
|
| 32 |
+
except ImportError:
|
| 33 |
+
WebShot = None
|
| 34 |
+
try:
|
| 35 |
+
from img2html.converter import Img2HTMLConverter
|
| 36 |
+
except ImportError:
|
| 37 |
+
Img2HTMLConverter = None
|
| 38 |
+
|
| 39 |
+
from . import async_searcher, get_random_user_data, get_string, re, ultroid_cmd
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
@ultroid_cmd(pattern="eod$")
|
| 43 |
+
async def diela(e):
|
| 44 |
+
m = await e.eor(get_string("com_1"))
|
| 45 |
+
li = "https://daysoftheyear.com"
|
| 46 |
+
te = "🎊 **Events of the Day**\n\n"
|
| 47 |
+
da = dt.now()
|
| 48 |
+
month = da.strftime("%b")
|
| 49 |
+
li += f"/days/{month}/" + da.strftime("%F").split("-")[2]
|
| 50 |
+
ct = await async_searcher(li, re_content=True)
|
| 51 |
+
bt = bs(ct, "html.parser", from_encoding="utf-8")
|
| 52 |
+
ml = bt.find_all("a", "js-link-target", href=re.compile("daysoftheyear.com/days"))
|
| 53 |
+
for eve in ml[:5]:
|
| 54 |
+
te += f'• [{eve.text}]({eve["href"]})\n'
|
| 55 |
+
await m.edit(te, link_preview=False)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
@ultroid_cmd(
|
| 59 |
+
pattern="pntrst( (.*)|$)",
|
| 60 |
+
)
|
| 61 |
+
async def pinterest(e):
|
| 62 |
+
m = e.pattern_match.group(1).strip()
|
| 63 |
+
if not m:
|
| 64 |
+
return await e.eor("`Give pinterest link.`", time=3)
|
| 65 |
+
soup = await async_searcher(
|
| 66 |
+
"https://www.expertstool.com/download-pinterest-video/",
|
| 67 |
+
data={"url": m},
|
| 68 |
+
post=True,
|
| 69 |
+
)
|
| 70 |
+
try:
|
| 71 |
+
_soup = bs(soup, "html.parser").find("table").tbody.find_all("tr")
|
| 72 |
+
except BaseException:
|
| 73 |
+
return await e.eor("`Wrong link or private pin.`", time=5)
|
| 74 |
+
file = _soup[1] if len(_soup) > 1 else _soup[0]
|
| 75 |
+
file = file.td.a["href"]
|
| 76 |
+
await e.client.send_file(e.chat_id, file, caption=f"Pin:- {m}")
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
@ultroid_cmd(pattern="gadget( (.*)|$)")
|
| 80 |
+
async def mobs(e):
|
| 81 |
+
mat = e.pattern_match.group(1).strip()
|
| 82 |
+
if not mat:
|
| 83 |
+
await e.eor("Please Give a Mobile Name to look for.")
|
| 84 |
+
query = mat.replace(" ", "%20")
|
| 85 |
+
jwala = f"https://gadgets.ndtv.com/search?searchtext={query}"
|
| 86 |
+
c = await async_searcher(jwala)
|
| 87 |
+
b = bs(c, "html.parser", from_encoding="utf-8")
|
| 88 |
+
co = b.find_all("div", "rvw-imgbox")
|
| 89 |
+
if not co:
|
| 90 |
+
return await e.eor("No Results Found!")
|
| 91 |
+
bt = await e.eor(get_string("com_1"))
|
| 92 |
+
out = "**📱 Mobile / Gadgets Search**\n\n"
|
| 93 |
+
li = co[0].find("a")
|
| 94 |
+
imu, title = None, li.find("img")["title"]
|
| 95 |
+
cont = await async_searcher(li["href"])
|
| 96 |
+
nu = bs(cont, "html.parser", from_encoding="utf-8")
|
| 97 |
+
req = nu.find_all("div", "_pdsd")
|
| 98 |
+
imu = nu.find_all(
|
| 99 |
+
"img", src=re.compile("https://i.gadgets360cdn.com/products/large/")
|
| 100 |
+
)
|
| 101 |
+
if imu:
|
| 102 |
+
imu = imu[0]["src"].split("?")[0] + "?downsize=*:420&output-quality=80"
|
| 103 |
+
out += f"☑️ **[{title}]({li['href']})**\n\n"
|
| 104 |
+
for fp in req:
|
| 105 |
+
ty = fp.findNext()
|
| 106 |
+
out += f"- **{ty.text}** - `{ty.findNext().text}`\n"
|
| 107 |
+
out += "_"
|
| 108 |
+
if imu == []:
|
| 109 |
+
imu = None
|
| 110 |
+
await e.reply(out, file=imu, link_preview=False)
|
| 111 |
+
await bt.delete()
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
@ultroid_cmd(pattern="randomuser")
|
| 115 |
+
async def _gen_data(event):
|
| 116 |
+
x = await event.eor(get_string("com_1"))
|
| 117 |
+
msg, pic = await get_random_user_data()
|
| 118 |
+
await event.reply(file=pic, message=msg)
|
| 119 |
+
await x.delete()
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
@ultroid_cmd(
|
| 123 |
+
pattern="ascii( (.*)|$)",
|
| 124 |
+
)
|
| 125 |
+
async def _(e):
|
| 126 |
+
if not Img2HTMLConverter:
|
| 127 |
+
return await e.eor("'img2html-converter' not installed!")
|
| 128 |
+
if not e.reply_to_msg_id:
|
| 129 |
+
return await e.eor(get_string("ascii_1"))
|
| 130 |
+
m = await e.eor(get_string("ascii_2"))
|
| 131 |
+
img = await (await e.get_reply_message()).download_media()
|
| 132 |
+
char = e.pattern_match.group(1).strip() or "■"
|
| 133 |
+
converter = Img2HTMLConverter(char=char)
|
| 134 |
+
html = converter.convert(img)
|
| 135 |
+
shot = WebShot(quality=85)
|
| 136 |
+
pic = await shot.create_pic_async(html=html)
|
| 137 |
+
await m.delete()
|
| 138 |
+
await e.reply(file=pic)
|
| 139 |
+
os.remove(pic)
|
| 140 |
+
os.remove(img)
|
plugins/mute.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}mute <reply to msg/ user id>`
|
| 11 |
+
Mute user in current chat.
|
| 12 |
+
|
| 13 |
+
• `{i}unmute <reply to msg/ user id>`
|
| 14 |
+
Unmute user in current chat.
|
| 15 |
+
|
| 16 |
+
• `{i}dmute <reply to msg/ user id>`
|
| 17 |
+
Mute user in current chat by deleting msgs.
|
| 18 |
+
|
| 19 |
+
• `{i}undmute <reply to msg/ use id>`
|
| 20 |
+
Unmute dmuted user in current chat.
|
| 21 |
+
|
| 22 |
+
• `{i}tmute <time> <reply to msg/ use id>`
|
| 23 |
+
s- seconds
|
| 24 |
+
m- minutes
|
| 25 |
+
h- hours
|
| 26 |
+
d- days
|
| 27 |
+
Mute user in current chat with time.
|
| 28 |
+
"""
|
| 29 |
+
from telethon import events
|
| 30 |
+
from telethon.utils import get_display_name
|
| 31 |
+
|
| 32 |
+
from pyUltroid.dB.mute_db import is_muted, mute, unmute
|
| 33 |
+
from pyUltroid.fns.admins import ban_time
|
| 34 |
+
|
| 35 |
+
from . import asst, eod, get_string, inline_mention, ultroid_bot, ultroid_cmd
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@ultroid_bot.on(events.NewMessage(incoming=True))
|
| 39 |
+
async def watcher(event):
|
| 40 |
+
if is_muted(event.chat_id, event.sender_id):
|
| 41 |
+
await event.delete()
|
| 42 |
+
if event.via_bot and is_muted(event.chat_id, event.via_bot_id):
|
| 43 |
+
await event.delete()
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
@ultroid_cmd(
|
| 47 |
+
pattern="dmute( (.*)|$)",
|
| 48 |
+
)
|
| 49 |
+
async def startmute(event):
|
| 50 |
+
xx = await event.eor("`Muting...`")
|
| 51 |
+
if input_ := event.pattern_match.group(1).strip():
|
| 52 |
+
try:
|
| 53 |
+
userid = await event.client.parse_id(input_)
|
| 54 |
+
except Exception as x:
|
| 55 |
+
return await xx.edit(str(x))
|
| 56 |
+
elif event.reply_to_msg_id:
|
| 57 |
+
reply = await event.get_reply_message()
|
| 58 |
+
userid = reply.sender_id
|
| 59 |
+
if reply.out or userid in [ultroid_bot.me.id, asst.me.id]:
|
| 60 |
+
return await xx.eor("`You cannot mute yourself or your assistant bot.`")
|
| 61 |
+
elif event.is_private:
|
| 62 |
+
userid = event.chat_id
|
| 63 |
+
else:
|
| 64 |
+
return await xx.eor("`Reply to a user or add their userid.`", time=5)
|
| 65 |
+
chat = await event.get_chat()
|
| 66 |
+
if "admin_rights" in vars(chat) and vars(chat)["admin_rights"] is not None:
|
| 67 |
+
if not chat.admin_rights.delete_messages:
|
| 68 |
+
return await xx.eor("`No proper admin rights...`", time=5)
|
| 69 |
+
elif "creator" not in vars(chat) and not event.is_private:
|
| 70 |
+
return await xx.eor("`No proper admin rights...`", time=5)
|
| 71 |
+
if is_muted(event.chat_id, userid):
|
| 72 |
+
return await xx.eor("`This user is already muted in this chat.`", time=5)
|
| 73 |
+
mute(event.chat_id, userid)
|
| 74 |
+
await xx.eor("`Successfully muted...`", time=3)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
@ultroid_cmd(
|
| 78 |
+
pattern="undmute( (.*)|$)",
|
| 79 |
+
)
|
| 80 |
+
async def endmute(event):
|
| 81 |
+
xx = await event.eor("`Unmuting...`")
|
| 82 |
+
if input_ := event.pattern_match.group(1).strip():
|
| 83 |
+
try:
|
| 84 |
+
userid = await event.client.parse_id(input_)
|
| 85 |
+
except Exception as x:
|
| 86 |
+
return await xx.edit(str(x))
|
| 87 |
+
elif event.reply_to_msg_id:
|
| 88 |
+
userid = (await event.get_reply_message()).sender_id
|
| 89 |
+
elif event.is_private:
|
| 90 |
+
userid = event.chat_id
|
| 91 |
+
else:
|
| 92 |
+
return await xx.eor("`Reply to a user or add their userid.`", time=5)
|
| 93 |
+
if not is_muted(event.chat_id, userid):
|
| 94 |
+
return await xx.eor("`This user is not muted in this chat.`", time=3)
|
| 95 |
+
unmute(event.chat_id, userid)
|
| 96 |
+
await xx.eor("`Successfully unmuted...`", time=3)
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@ultroid_cmd(
|
| 100 |
+
pattern="tmute",
|
| 101 |
+
groups_only=True,
|
| 102 |
+
manager=True,
|
| 103 |
+
)
|
| 104 |
+
async def _(e):
|
| 105 |
+
xx = await e.eor("`Muting...`")
|
| 106 |
+
huh = e.text.split()
|
| 107 |
+
try:
|
| 108 |
+
tme = huh[1]
|
| 109 |
+
except IndexError:
|
| 110 |
+
return await xx.eor("`Time till mute?`", time=5)
|
| 111 |
+
try:
|
| 112 |
+
input_ = huh[2]
|
| 113 |
+
except IndexError:
|
| 114 |
+
input_ = ""
|
| 115 |
+
chat = await e.get_chat()
|
| 116 |
+
if e.reply_to_msg_id:
|
| 117 |
+
reply = await e.get_reply_message()
|
| 118 |
+
userid = reply.sender_id
|
| 119 |
+
name = (await reply.get_sender()).first_name
|
| 120 |
+
elif input_:
|
| 121 |
+
userid = await e.client.parse_id(input_)
|
| 122 |
+
name = (await e.client.get_entity(userid)).first_name
|
| 123 |
+
else:
|
| 124 |
+
return await xx.eor(get_string("tban_1"), time=3)
|
| 125 |
+
if userid == ultroid_bot.uid:
|
| 126 |
+
return await xx.eor("`I can't mute myself.`", time=3)
|
| 127 |
+
try:
|
| 128 |
+
bun = ban_time(tme)
|
| 129 |
+
await e.client.edit_permissions(
|
| 130 |
+
chat.id,
|
| 131 |
+
userid,
|
| 132 |
+
until_date=bun,
|
| 133 |
+
send_messages=False,
|
| 134 |
+
)
|
| 135 |
+
await eod(
|
| 136 |
+
xx,
|
| 137 |
+
f"`Successfully Muted` [{name}](tg://user?id={userid}) `in {chat.title} for {tme}`",
|
| 138 |
+
time=5,
|
| 139 |
+
)
|
| 140 |
+
except BaseException as m:
|
| 141 |
+
await xx.eor(f"`{m}`", time=5)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
@ultroid_cmd(
|
| 145 |
+
pattern="unmute( (.*)|$)",
|
| 146 |
+
admins_only=True,
|
| 147 |
+
manager=True,
|
| 148 |
+
)
|
| 149 |
+
async def _(e):
|
| 150 |
+
xx = await e.eor("`Unmuting...`")
|
| 151 |
+
input = e.pattern_match.group(1).strip()
|
| 152 |
+
chat = await e.get_chat()
|
| 153 |
+
if e.reply_to_msg_id:
|
| 154 |
+
reply = await e.get_reply_message()
|
| 155 |
+
userid = reply.sender_id
|
| 156 |
+
name = (await reply.get_sender()).first_name
|
| 157 |
+
elif input:
|
| 158 |
+
userid = await e.client.parse_id(input)
|
| 159 |
+
name = (await e.client.get_entity(userid)).first_name
|
| 160 |
+
else:
|
| 161 |
+
return await xx.eor(get_string("tban_1"), time=3)
|
| 162 |
+
try:
|
| 163 |
+
await e.client.edit_permissions(
|
| 164 |
+
chat.id,
|
| 165 |
+
userid,
|
| 166 |
+
until_date=None,
|
| 167 |
+
send_messages=True,
|
| 168 |
+
)
|
| 169 |
+
await eod(
|
| 170 |
+
xx,
|
| 171 |
+
f"`Successfully Unmuted` [{name}](tg://user?id={userid}) `in {chat.title}`",
|
| 172 |
+
time=5,
|
| 173 |
+
)
|
| 174 |
+
except BaseException as m:
|
| 175 |
+
await xx.eor(f"`{m}`", time=5)
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
@ultroid_cmd(
|
| 179 |
+
pattern="mute( (.*)|$)", admins_only=True, manager=True, require="ban_users"
|
| 180 |
+
)
|
| 181 |
+
async def _(e):
|
| 182 |
+
xx = await e.eor("`Muting...`")
|
| 183 |
+
input = e.pattern_match.group(1).strip()
|
| 184 |
+
chat = await e.get_chat()
|
| 185 |
+
if e.reply_to_msg_id:
|
| 186 |
+
userid = (await e.get_reply_message()).sender_id
|
| 187 |
+
name = get_display_name(await e.client.get_entity(userid))
|
| 188 |
+
elif input:
|
| 189 |
+
try:
|
| 190 |
+
userid = await e.client.parse_id(input)
|
| 191 |
+
name = inline_mention(await e.client.get_entity(userid))
|
| 192 |
+
except Exception as x:
|
| 193 |
+
return await xx.edit(str(x))
|
| 194 |
+
else:
|
| 195 |
+
return await xx.eor(get_string("tban_1"), time=3)
|
| 196 |
+
if userid == ultroid_bot.uid:
|
| 197 |
+
return await xx.eor("`I can't mute myself.`", time=3)
|
| 198 |
+
try:
|
| 199 |
+
await e.client.edit_permissions(
|
| 200 |
+
chat.id,
|
| 201 |
+
userid,
|
| 202 |
+
until_date=None,
|
| 203 |
+
send_messages=False,
|
| 204 |
+
)
|
| 205 |
+
await eod(
|
| 206 |
+
xx,
|
| 207 |
+
f"`Successfully Muted` {name} `in {chat.title}`",
|
| 208 |
+
)
|
| 209 |
+
except BaseException as m:
|
| 210 |
+
await xx.eor(f"`{m}`", time=5)
|
plugins/nightmode.py
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
At Night it will turn off everyone permission to send message in an all groups which you added via `{i}addnight`
|
| 11 |
+
And Turn On auto at morning
|
| 12 |
+
|
| 13 |
+
• `{i}addnm`
|
| 14 |
+
Add NightMode
|
| 15 |
+
To Add Group To Auto Night Mode.
|
| 16 |
+
|
| 17 |
+
• `{i}remnm`
|
| 18 |
+
Remove NightMode
|
| 19 |
+
To remove Group From Auto Night Mode
|
| 20 |
+
|
| 21 |
+
• `{i}listnm`
|
| 22 |
+
List NightMode
|
| 23 |
+
To Get All List of Groups where NightMode Active.
|
| 24 |
+
|
| 25 |
+
• `{i}nmtime <close hour> <close min> <open hour> <open min>`
|
| 26 |
+
NightMode Time
|
| 27 |
+
By Default Its close 00:00 , open 07:00
|
| 28 |
+
Use 24hr format
|
| 29 |
+
Ex- `nmtime 01 00 06 30`
|
| 30 |
+
"""
|
| 31 |
+
|
| 32 |
+
from . import LOGS
|
| 33 |
+
|
| 34 |
+
try:
|
| 35 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
| 36 |
+
except ImportError:
|
| 37 |
+
LOGS.error("nightmode: 'apscheduler' not Installed!")
|
| 38 |
+
AsyncIOScheduler = None
|
| 39 |
+
|
| 40 |
+
from telethon.tl.functions.messages import EditChatDefaultBannedRightsRequest
|
| 41 |
+
from telethon.tl.types import ChatBannedRights
|
| 42 |
+
|
| 43 |
+
from pyUltroid.dB.base import KeyManager
|
| 44 |
+
|
| 45 |
+
from . import get_string, udB, ultroid_bot, ultroid_cmd
|
| 46 |
+
|
| 47 |
+
keym = KeyManager("NIGHT_CHATS", cast=list)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
@ultroid_cmd(pattern="nmtime( (.*)|$)")
|
| 51 |
+
async def set_time(e):
|
| 52 |
+
if not e.pattern_match.group(1).strip():
|
| 53 |
+
return await e.eor(get_string("nightm_1"))
|
| 54 |
+
try:
|
| 55 |
+
ok = e.text.split(maxsplit=1)[1].split()
|
| 56 |
+
if len(ok) != 4:
|
| 57 |
+
return await e.eor(get_string("nightm_1"))
|
| 58 |
+
tm = [int(x) for x in ok]
|
| 59 |
+
udB.set_key("NIGHT_TIME", str(tm))
|
| 60 |
+
await e.eor(get_string("nightm_2"))
|
| 61 |
+
except BaseException:
|
| 62 |
+
await e.eor(get_string("nightm_1"))
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
@ultroid_cmd(pattern="addnm( (.*)|$)")
|
| 66 |
+
async def add_grp(e):
|
| 67 |
+
if pat := e.pattern_match.group(1).strip():
|
| 68 |
+
try:
|
| 69 |
+
keym.add((await ultroid_bot.get_entity(pat)).id)
|
| 70 |
+
return await e.eor(f"Done, Added {pat} To Night Mode.")
|
| 71 |
+
except BaseException:
|
| 72 |
+
return await e.eor(get_string("nightm_5"), time=5)
|
| 73 |
+
keym.add(e.chat_id)
|
| 74 |
+
await e.eor(get_string("nightm_3"))
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
@ultroid_cmd(pattern="remnm( (.*)|$)")
|
| 78 |
+
async def r_em_grp(e):
|
| 79 |
+
if pat := e.pattern_match.group(1).strip():
|
| 80 |
+
try:
|
| 81 |
+
keym.remove((await ultroid_bot.get_entity(pat)).id)
|
| 82 |
+
return await e.eor(f"Done, Removed {pat} To Night Mode.")
|
| 83 |
+
except BaseException:
|
| 84 |
+
return await e.eor(get_string("nightm_5"), time=5)
|
| 85 |
+
keym.remove(e.chat_id)
|
| 86 |
+
await e.eor(get_string("nightm_4"))
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
@ultroid_cmd(pattern="listnm$")
|
| 90 |
+
async def rem_grp(e):
|
| 91 |
+
chats = keym.get()
|
| 92 |
+
name = "NightMode Groups Are-:\n\n"
|
| 93 |
+
for x in chats:
|
| 94 |
+
try:
|
| 95 |
+
ok = await ultroid_bot.get_entity(x)
|
| 96 |
+
name += f"@{ok.username}" if ok.username else ok.title
|
| 97 |
+
except BaseException:
|
| 98 |
+
name += str(x)
|
| 99 |
+
await e.eor(name)
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
async def open_grp():
|
| 103 |
+
for chat in keym.get():
|
| 104 |
+
try:
|
| 105 |
+
await ultroid_bot(
|
| 106 |
+
EditChatDefaultBannedRightsRequest(
|
| 107 |
+
chat,
|
| 108 |
+
banned_rights=ChatBannedRights(
|
| 109 |
+
until_date=None,
|
| 110 |
+
send_messages=False,
|
| 111 |
+
send_media=False,
|
| 112 |
+
send_stickers=False,
|
| 113 |
+
send_gifs=False,
|
| 114 |
+
send_games=False,
|
| 115 |
+
send_inline=False,
|
| 116 |
+
send_polls=False,
|
| 117 |
+
),
|
| 118 |
+
)
|
| 119 |
+
)
|
| 120 |
+
await ultroid_bot.send_message(chat, "**NightMode Off**\n\nGroup Opened 🥳.")
|
| 121 |
+
except Exception as er:
|
| 122 |
+
LOGS.info(er)
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
async def close_grp():
|
| 126 |
+
__, _, h2, m2 = 0, 0, 7, 0
|
| 127 |
+
if udB.get_key("NIGHT_TIME"):
|
| 128 |
+
_, __, h2, m2 = eval(udB.get_key("NIGHT_TIME"))
|
| 129 |
+
for chat in keym.get():
|
| 130 |
+
try:
|
| 131 |
+
await ultroid_bot(
|
| 132 |
+
EditChatDefaultBannedRightsRequest(
|
| 133 |
+
chat,
|
| 134 |
+
banned_rights=ChatBannedRights(
|
| 135 |
+
until_date=None,
|
| 136 |
+
send_messages=True,
|
| 137 |
+
),
|
| 138 |
+
)
|
| 139 |
+
)
|
| 140 |
+
await ultroid_bot.send_message(
|
| 141 |
+
chat, f"**NightMode : Group Closed**\n\nGroup Will Open At `{h2}:{m2}`"
|
| 142 |
+
)
|
| 143 |
+
except Exception as er:
|
| 144 |
+
LOGS.info(er)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
if AsyncIOScheduler and keym.get():
|
| 148 |
+
try:
|
| 149 |
+
h1, m1, h2, m2 = 0, 0, 7, 0
|
| 150 |
+
if udB.get_key("NIGHT_TIME"):
|
| 151 |
+
h1, m1, h2, m2 = eval(udB.get_key("NIGHT_TIME"))
|
| 152 |
+
sch = AsyncIOScheduler()
|
| 153 |
+
sch.add_job(close_grp, trigger="cron", hour=h1, minute=m1)
|
| 154 |
+
sch.add_job(open_grp, trigger="cron", hour=h2, minute=m2)
|
| 155 |
+
sch.start()
|
| 156 |
+
except Exception as er:
|
| 157 |
+
LOGS.info(er)
|
plugins/notes.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ultroid - UserBot
|
| 2 |
+
# Copyright (C) 2021-2025 TeamUltroid
|
| 3 |
+
#
|
| 4 |
+
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
|
| 5 |
+
# PLease read the GNU Affero General Public License in
|
| 6 |
+
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
|
| 7 |
+
"""
|
| 8 |
+
✘ Commands Available -
|
| 9 |
+
|
| 10 |
+
• `{i}addnote <word><reply to a message>`
|
| 11 |
+
add note in the used chat with replied message and choosen word.
|
| 12 |
+
|
| 13 |
+
• `{i}remnote <word>`
|
| 14 |
+
Remove the note from used chat.
|
| 15 |
+
|
| 16 |
+
• `{i}listnote`
|
| 17 |
+
list all notes.
|
| 18 |
+
|
| 19 |
+
• Use :
|
| 20 |
+
set notes in group so all can use it.
|
| 21 |
+
type `#(Keyword of note)` to get it
|
| 22 |
+
"""
|
| 23 |
+
import os
|
| 24 |
+
|
| 25 |
+
from . import upload_file as uf
|
| 26 |
+
from telethon.utils import pack_bot_file_id
|
| 27 |
+
|
| 28 |
+
from pyUltroid.dB.notes_db import add_note, get_notes, list_note, rem_note
|
| 29 |
+
from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button
|
| 30 |
+
|
| 31 |
+
from . import events, get_string, mediainfo, udB, ultroid_bot, ultroid_cmd
|
| 32 |
+
from ._inline import something
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
@ultroid_cmd(pattern="addnote( (.*)|$)", admins_only=True)
|
| 36 |
+
async def an(e):
|
| 37 |
+
wrd = (e.pattern_match.group(1).strip()).lower()
|
| 38 |
+
wt = await e.get_reply_message()
|
| 39 |
+
chat = e.chat_id
|
| 40 |
+
if not (wt and wrd):
|
| 41 |
+
return await e.eor(get_string("notes_1"), time=5)
|
| 42 |
+
if "#" in wrd:
|
| 43 |
+
wrd = wrd.replace("#", "")
|
| 44 |
+
btn = format_btn(wt.buttons) if wt.buttons else None
|
| 45 |
+
if wt and wt.media:
|
| 46 |
+
wut = mediainfo(wt.media)
|
| 47 |
+
if wut.startswith(("pic", "gif")):
|
| 48 |
+
dl = await wt.download_media()
|
| 49 |
+
m = uf(dl)
|
| 50 |
+
os.remove(dl)
|
| 51 |
+
elif wut == "video":
|
| 52 |
+
if wt.media.document.size > 8 * 1000 * 1000:
|
| 53 |
+
return await e.eor(get_string("com_4"), time=5)
|
| 54 |
+
dl = await wt.download_media()
|
| 55 |
+
m = uf(dl)
|
| 56 |
+
os.remove(dl)
|
| 57 |
+
else:
|
| 58 |
+
m = pack_bot_file_id(wt.media)
|
| 59 |
+
if wt.text:
|
| 60 |
+
txt = wt.text
|
| 61 |
+
if not btn:
|
| 62 |
+
txt, btn = get_msg_button(wt.text)
|
| 63 |
+
add_note(chat, wrd, txt, m, btn)
|
| 64 |
+
else:
|
| 65 |
+
add_note(chat, wrd, None, m, btn)
|
| 66 |
+
else:
|
| 67 |
+
txt = wt.text
|
| 68 |
+
if not btn:
|
| 69 |
+
txt, btn = get_msg_button(wt.text)
|
| 70 |
+
add_note(chat, wrd, txt, None, btn)
|
| 71 |
+
await e.eor(get_string("notes_2").format(wrd))
|
| 72 |
+
ultroid_bot.add_handler(notes, events.NewMessage())
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
@ultroid_cmd(pattern="remnote( (.*)|$)", admins_only=True)
|
| 76 |
+
async def rn(e):
|
| 77 |
+
wrd = (e.pattern_match.group(1).strip()).lower()
|
| 78 |
+
chat = e.chat_id
|
| 79 |
+
if not wrd:
|
| 80 |
+
return await e.eor(get_string("notes_3"), time=5)
|
| 81 |
+
if wrd.startswith("#"):
|
| 82 |
+
wrd = wrd.replace("#", "")
|
| 83 |
+
rem_note(int(chat), wrd)
|
| 84 |
+
await e.eor(f"Done Note: `#{wrd}` Removed.")
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
@ultroid_cmd(pattern="listnote$", admins_only=True)
|
| 88 |
+
async def lsnote(e):
|
| 89 |
+
if x := list_note(e.chat_id):
|
| 90 |
+
sd = "Notes Found In This Chats Are\n\n"
|
| 91 |
+
return await e.eor(sd + x)
|
| 92 |
+
await e.eor(get_string("notes_5"))
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
async def notes(e):
|
| 96 |
+
xx = [z.replace("#", "") for z in e.text.lower().split() if z.startswith("#")]
|
| 97 |
+
for word in xx:
|
| 98 |
+
if k := get_notes(e.chat_id, word):
|
| 99 |
+
msg = k["msg"]
|
| 100 |
+
media = k["media"]
|
| 101 |
+
if k.get("button"):
|
| 102 |
+
btn = create_tl_btn(k["button"])
|
| 103 |
+
return await something(e, msg, media, btn)
|
| 104 |
+
await e.client.send_message(
|
| 105 |
+
e.chat_id, msg, file=media, reply_to=e.reply_to_msg_id or e.id
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
if udB.get_key("NOTE"):
|
| 110 |
+
ultroid_bot.add_handler(notes, events.NewMessage())
|