abhay2245 commited on
Commit
f3e30ac
·
verified ·
1 Parent(s): 58afac5

Upload 83 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
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())