azils3 commited on
Commit
618430a
·
verified ·
1 Parent(s): 0ef832b

Upload 216 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
.gitattributes CHANGED
@@ -33,3 +33,13 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ resources/extras/logo_readme.jpg filter=lfs diff=lfs merge=lfs -text
37
+ resources/extras/ultroid.jpg filter=lfs diff=lfs merge=lfs -text
38
+ resources/fonts/11.otf filter=lfs diff=lfs merge=lfs -text
39
+ resources/fonts/3.ttf filter=lfs diff=lfs merge=lfs -text
40
+ resources/fonts/default.ttf filter=lfs diff=lfs merge=lfs -text
41
+ resources/fonts/DroidSansMono.ttf filter=lfs diff=lfs merge=lfs -text
42
+ resources/fonts/Quivira.otf filter=lfs diff=lfs merge=lfs -text
43
+ resources/fonts/Roboto-Italic.ttf filter=lfs diff=lfs merge=lfs -text
44
+ resources/fonts/Roboto-Medium.ttf filter=lfs diff=lfs merge=lfs -text
45
+ resources/fonts/Roboto-Regular.ttf filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .env
2
+ *.session-journal
3
+ *.session
4
+ build
5
+ test*
6
+ *.mp3
7
+ *.webm
8
+ *.webp
9
+ *.mp4
10
+ *.tgs
11
+ *.txt
12
+ /*.jpg
13
+ /*.png
14
+ /*.mp4
15
+ *.log
16
+ target/npmlist.json
17
+ package-lock.json
18
+ ultroid.json
19
+ resources/extras/thumbnail.jpg
20
+ resources/auth/
21
+
22
+ # Directories
23
+ addons/
24
+ vcbot/
25
+ __pycache__/
26
+ venv/
27
+ node_modules/
28
+ glitch_me/
29
+ src/glitch-me
30
+ .idea/
31
+ .vscode/
32
+ temp/
33
+ bin-debug/
34
+ bin-release/
35
+ [Oo]bj/
36
+ [Bb]in/
37
+ .settings/
38
+ *.swf
39
+ *.air
40
+ *.ipa
41
+ *.apk
42
+
43
+ # temporary files
44
+ *.raw
45
+
46
+ # fly.io configs
47
+ fly.toml
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Ultroid - UserBot
2
+ # Copyright (C) 2021-2025 TeamUltroid
3
+ # This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
4
+ # PLease read the GNU Affero General Public License in <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
5
+
6
+ FROM theteamultroid/ultroid:main
7
+
8
+ # set timezone
9
+ ENV TZ=Asia/Karachi
10
+ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
11
+
12
+ COPY installer.sh .
13
+
14
+ RUN bash installer.sh
15
+
16
+ # changing workdir
17
+ WORKDIR "/root/TeamUltroid"
18
+
19
+ # start the bot.
20
+ CMD ["bash", "startup"]
assistant/__init__.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 import Button, custom
9
+
10
+ from plugins import ATRA_COL, InlinePlugin
11
+ from pyUltroid import *
12
+ from pyUltroid import _ult_cache
13
+ from pyUltroid._misc import owner_and_sudos
14
+ from pyUltroid._misc._assistant import asst_cmd, callback, in_pattern
15
+ from pyUltroid.fns.helper import *
16
+ from pyUltroid.fns.tools import get_stored_file
17
+ from strings import get_languages, get_string
18
+
19
+ OWNER_NAME = ultroid_bot.full_name
20
+ OWNER_ID = ultroid_bot.uid
21
+
22
+ AST_PLUGINS = {}
23
+
24
+
25
+ async def setit(event, name, value):
26
+ try:
27
+ udB.set_key(name, value)
28
+ except BaseException as er:
29
+ LOGS.exception(er)
30
+ return await event.edit("`Something Went Wrong`")
31
+
32
+
33
+ def get_back_button(name):
34
+ return [Button.inline("« Bᴀᴄᴋ", data=f"{name}")]
assistant/callbackstuffs.py ADDED
@@ -0,0 +1,1318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ast
9
+ import asyncio
10
+ import re
11
+ import sys
12
+ import time
13
+ from asyncio.exceptions import TimeoutError as AsyncTimeOut
14
+ from os import execl, remove
15
+ from random import choice
16
+
17
+ from bs4 import BeautifulSoup as bs
18
+
19
+ try:
20
+ from pyUltroid.fns.gDrive import GDriveManager
21
+ except ImportError:
22
+ GDriveManager = None
23
+ from telethon import Button, events
24
+ from catbox import CatboxUploader
25
+ from telethon.tl.types import MessageMediaWebPage
26
+ from telethon.utils import get_peer_id
27
+
28
+ from pyUltroid.fns.helper import fast_download, progress
29
+ from pyUltroid.fns.tools import Carbon, async_searcher, get_paste, telegraph_client
30
+ from pyUltroid.startup.loader import Loader
31
+
32
+ from . import *
33
+
34
+ # --------------------------------------------------------------------#
35
+ telegraph = telegraph_client()
36
+ GDrive = GDriveManager() if GDriveManager else None
37
+ uploader = CatboxUploader()
38
+ # --------------------------------------------------------------------#
39
+
40
+ def text_to_url(event):
41
+ """function to get media url (with|without) Webpage"""
42
+ if isinstance(event.media, MessageMediaWebPage):
43
+ webpage = event.media.webpage
44
+ if not isinstance(webpage, types.WebPageEmpty) and webpage.type in ["photo"]:
45
+ return webpage.display_url
46
+ return event.text
47
+
48
+
49
+ # --------------------------------------------------------------------#
50
+
51
+ _buttons = {
52
+ "otvars": {
53
+ "text": "Other Variables to set for @TeamUltroid:",
54
+ "buttons": [
55
+ [
56
+ Button.inline("Tᴀɢ Lᴏɢɢᴇʀ", data="taglog"),
57
+ Button.inline("SᴜᴘᴇʀFʙᴀɴ", data="cbs_sfban"),
58
+ ],
59
+ [
60
+ Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ", data="sudo"),
61
+ Button.inline("Hᴀɴᴅʟᴇʀ", data="hhndlr"),
62
+ ],
63
+ [
64
+ Button.inline("Exᴛʀᴀ Pʟᴜɢɪɴs", data="plg"),
65
+ Button.inline("Aᴅᴅᴏɴs", data="eaddon"),
66
+ ],
67
+ [
68
+ Button.inline("Eᴍᴏᴊɪ ɪɴ Hᴇʟᴘ", data="emoj"),
69
+ Button.inline("Sᴇᴛ ɢDʀɪᴠᴇ", data="gdrive"),
70
+ ],
71
+ [
72
+ Button.inline("Iɴʟɪɴᴇ Pɪᴄ", data="inli_pic"),
73
+ Button.inline("Sᴜᴅᴏ HNDLR", data="shndlr"),
74
+ ],
75
+ [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ", "cbs_oofdm")],
76
+ [Button.inline("« Bᴀᴄᴋ", data="setter")],
77
+ ],
78
+ },
79
+ "sfban": {
80
+ "text": "SuperFban Settings:",
81
+ "buttons": [
82
+ [Button.inline("FBᴀɴ Gʀᴏᴜᴘ", data="sfgrp")],
83
+ [Button.inline("Exᴄʟᴜᴅᴇ Fᴇᴅs", data="abs_sfexf")],
84
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")],
85
+ ],
86
+ },
87
+ "apauto": {
88
+ "text": "This'll auto approve on outgoing messages",
89
+ "buttons": [
90
+ [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ ON", data="apon")],
91
+ [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ OFF", data="apof")],
92
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")],
93
+ ],
94
+ },
95
+ "alvcstm": {
96
+ "text": f"Customise your {HNDLR}alive. Choose from the below options -",
97
+ "buttons": [
98
+ [Button.inline("Aʟɪᴠᴇ Tᴇxᴛ", data="abs_alvtx")],
99
+ [Button.inline("Aʟɪᴠᴇ ᴍᴇᴅɪᴀ", data="alvmed")],
100
+ [Button.inline("Dᴇʟᴇᴛᴇ Aʟɪᴠᴇ Mᴇᴅɪᴀ", data="delmed")],
101
+ [Button.inline("« Bᴀᴄᴋ", data="setter")],
102
+ ],
103
+ },
104
+ "pmcstm": {
105
+ "text": "Customise your PMPERMIT Settings -",
106
+ "buttons": [
107
+ [
108
+ Button.inline("Pᴍ Tᴇxᴛ", data="pmtxt"),
109
+ Button.inline("Pᴍ Mᴇᴅɪᴀ", data="pmmed"),
110
+ ],
111
+ [
112
+ Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ", data="cbs_apauto"),
113
+ Button.inline("PMLOGGER", data="pml"),
114
+ ],
115
+ [
116
+ Button.inline("Sᴇᴛ Wᴀʀɴs", data="swarn"),
117
+ Button.inline("Dᴇʟᴇᴛᴇ Pᴍ Mᴇᴅɪᴀ", data="delpmmed"),
118
+ ],
119
+ [Button.inline("PMPermit Type", data="cbs_pmtype")],
120
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")],
121
+ ],
122
+ },
123
+ "pmtype": {
124
+ "text": "Select the type of PMPermit needed.",
125
+ "buttons": [
126
+ [Button.inline("Inline", data="inpm_in")],
127
+ [Button.inline("Normal", data="inpm_no")],
128
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")],
129
+ ],
130
+ },
131
+ "ppmset": {
132
+ "text": "PMPermit Settings:",
133
+ "buttons": [
134
+ [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oɴ", data="pmon")],
135
+ [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oғғ", data="pmoff")],
136
+ [Button.inline("Cᴜsᴛᴏᴍɪᴢᴇ PMPᴇʀᴍɪᴛ", data="cbs_pmcstm")],
137
+ [Button.inline("« Bᴀᴄᴋ", data="setter")],
138
+ ],
139
+ },
140
+ "chatbot": {
141
+ "text": "From This Feature U can chat with ppls Via ur Assistant Bot.\n[More info](https://t.me/UltroidUpdates/2)",
142
+ "buttons": [
143
+ [
144
+ Button.inline("Cʜᴀᴛ Bᴏᴛ Oɴ", data="onchbot"),
145
+ Button.inline("Cʜᴀᴛ Bᴏᴛ Oғғ", data="ofchbot"),
146
+ ],
147
+ [
148
+ Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ", data="bwel"),
149
+ Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ Mᴇᴅɪᴀ", data="botmew"),
150
+ ],
151
+ [Button.inline("Bᴏᴛ Iɴғᴏ Tᴇxᴛ", data="botinfe")],
152
+ [Button.inline("Fᴏʀᴄᴇ Sᴜʙsᴄʀɪʙᴇ", data="pmfs")],
153
+ [Button.inline("« Bᴀᴄᴋ", data="setter")],
154
+ ],
155
+ },
156
+ "vcb": {
157
+ "text": "From This Feature U can play songs in group voice chat\n\n[moreinfo](https://t.me/UltroidUpdates/4)",
158
+ "buttons": [
159
+ [Button.inline("VC Sᴇssɪᴏɴ", data="abs_vcs")],
160
+ [Button.inline("« Bᴀᴄᴋ", data="setter")],
161
+ ],
162
+ },
163
+ "oofdm": {
164
+ "text": "About [Dual Mode](https://t.me/UltroidUpdates/18)",
165
+ "buttons": [
166
+ [
167
+ Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oɴ", "dmof"),
168
+ Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oғғ", "dmof"),
169
+ ],
170
+ [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Hɴᴅʟʀ", "dmhn")],
171
+ [Button.inline("« Back", data="cbs_otvars")],
172
+ ],
173
+ },
174
+ "apiset": {
175
+ "text": get_string("ast_1"),
176
+ "buttons": [
177
+ [Button.inline("Remove.bg API", data="abs_rmbg")],
178
+ [Button.inline("DEEP API", data="abs_dapi")],
179
+ [Button.inline("OCR API", data="abs_oapi")],
180
+ [Button.inline("« Back", data="setter")],
181
+ ],
182
+ },
183
+ }
184
+
185
+ _convo = {
186
+ "rmbg": {
187
+ "var": "RMBG_API",
188
+ "name": "Remove.bg API Key",
189
+ "text": get_string("ast_2"),
190
+ "back": "cbs_apiset",
191
+ },
192
+ "dapi": {
193
+ "var": "DEEP_AI",
194
+ "name": "Deep AI Api Key",
195
+ "text": "Get Your Deep Api from deepai.org and send here.",
196
+ "back": "cbs_apiset",
197
+ },
198
+ "oapi": {
199
+ "var": "OCR_API",
200
+ "name": "Ocr Api Key",
201
+ "text": "Get Your OCR api from ocr.space and send that Here.",
202
+ "back": "cbs_apiset",
203
+ },
204
+ "pmlgg": {
205
+ "var": "PMLOGGROUP",
206
+ "name": "Pm Log Group",
207
+ "text": "Send chat id of chat which you want to save as Pm log Group.",
208
+ "back": "pml",
209
+ },
210
+ "vcs": {
211
+ "var": "VC_SESSION",
212
+ "name": "Vc Session",
213
+ "text": "**Vc session**\nEnter the New session u generated for vc bot.\n\nUse /cancel to terminate the operation.",
214
+ "back": "cbs_vcb",
215
+ },
216
+ "settag": {
217
+ "var": "TAG_LOG",
218
+ "name": "Tag Log Group",
219
+ "text": f"Make a group, add your assistant and make it admin.\nGet the `{HNDLR}id` of that group and send it here for tag logs.\n\nUse /cancel to cancel.",
220
+ "back": "taglog",
221
+ },
222
+ "alvtx": {
223
+ "var": "ALIVE_TEXT",
224
+ "name": "Alive Text",
225
+ "text": "**Alive Text**\nEnter the new alive text.\n\nUse /cancel to terminate the operation.",
226
+ "back": "cbs_alvcstm",
227
+ },
228
+ "sfexf": {
229
+ "var": "EXCLUDE_FED",
230
+ "name": "Excluded Fed",
231
+ "text": "Send the Fed IDs you want to exclude in the ban. Split by a space.\neg`id1 id2 id3`\nSet is as `None` if you dont want any.\nUse /cancel to go back.",
232
+ "back": "cbs_sfban",
233
+ },
234
+ }
235
+
236
+
237
+ TOKEN_FILE = "resources/auths/auth_token.txt"
238
+
239
+
240
+ @callback(
241
+ re.compile(
242
+ "sndplug_(.*)",
243
+ ),
244
+ owner=True,
245
+ )
246
+ async def send(eve):
247
+ key, name = (eve.data_match.group(1)).decode("UTF-8").split("_")
248
+ thumb = "resources/extras/inline.jpg"
249
+ await eve.answer("■ Sending ■")
250
+ data = f"uh_{key}_"
251
+ index = None
252
+ if "|" in name:
253
+ name, index = name.split("|")
254
+ key = "plugins" if key == "Official" else key.lower()
255
+ plugin = f"{key}/{name}.py"
256
+ _ = f"pasta-{plugin}"
257
+ if index is not None:
258
+ data += f"|{index}"
259
+ _ += f"|{index}"
260
+ buttons = [
261
+ [
262
+ Button.inline(
263
+ "« Pᴀsᴛᴇ »",
264
+ data=_,
265
+ )
266
+ ],
267
+ [
268
+ Button.inline("« Bᴀᴄᴋ", data=data),
269
+ ],
270
+ ]
271
+ try:
272
+ await eve.edit(file=plugin, thumb=thumb, buttons=buttons)
273
+ except Exception as er:
274
+ await eve.answer(str(er), alert=True)
275
+
276
+
277
+ heroku_api, app_name = Var.HEROKU_API, Var.HEROKU_APP_NAME
278
+
279
+
280
+ @callback("updatenow", owner=True)
281
+ async def update(eve):
282
+ repo = Repo()
283
+ ac_br = repo.active_branch
284
+ ups_rem = repo.remote("upstream")
285
+ if heroku_api:
286
+ import heroku3
287
+
288
+ try:
289
+ heroku = heroku3.from_key(heroku_api)
290
+ heroku_app = None
291
+ heroku_applications = heroku.apps()
292
+ except BaseException as er:
293
+ LOGS.exception(er)
294
+ return await eve.edit("`Wrong HEROKU_API.`")
295
+ for app in heroku_applications:
296
+ if app.name == app_name:
297
+ heroku_app = app
298
+ if not heroku_app:
299
+ await eve.edit("`Wrong HEROKU_APP_NAME.`")
300
+ repo.__del__()
301
+ return
302
+ await eve.edit(get_string("clst_1"))
303
+ ups_rem.fetch(ac_br)
304
+ repo.git.reset("--hard", "FETCH_HEAD")
305
+ heroku_git_url = heroku_app.git_url.replace(
306
+ "https://", f"https://api:{heroku_api}@"
307
+ )
308
+
309
+ if "heroku" in repo.remotes:
310
+ remote = repo.remote("heroku")
311
+ remote.set_url(heroku_git_url)
312
+ else:
313
+ remote = repo.create_remote("heroku", heroku_git_url)
314
+ try:
315
+ remote.push(refspec=f"HEAD:refs/heads/{ac_br}", force=True)
316
+ except GitCommandError as error:
317
+ await eve.edit(f"`Here is the error log:\n{error}`")
318
+ repo.__del__()
319
+ return
320
+ await eve.edit("`Successfully Updated!\nRestarting, please wait...`")
321
+ else:
322
+ await eve.edit(get_string("clst_1"))
323
+ call_back()
324
+ await bash("git pull && pip3 install -r requirements.txt")
325
+ await bash("pip3 install -r requirements.txt --break-system-packages")
326
+ execl(sys.executable, sys.executable, "-m", "pyUltroid")
327
+
328
+ @callback(re.compile("changes(.*)"), owner=True)
329
+ async def changes(okk):
330
+ match = okk.data_match.group(1).decode("utf-8")
331
+ await okk.answer(get_string("clst_3"))
332
+ repo = Repo.init()
333
+ button = [[Button.inline("Update Now", data="updatenow")]]
334
+ changelog, tl_chnglog = await gen_chlog(
335
+ repo, f"HEAD..upstream/{repo.active_branch}"
336
+ )
337
+ cli = "\n\nClick the below button to update!"
338
+ if not match:
339
+ try:
340
+ if len(tl_chnglog) > 700:
341
+ tl_chnglog = f"{tl_chnglog[:700]}..."
342
+ button.append([Button.inline("View Complete", "changesall")])
343
+ await okk.edit("• Writing Changelogs 📝 •")
344
+ img = await Carbon(
345
+ file_name="changelog",
346
+ code=tl_chnglog,
347
+ backgroundColor=choice(ATRA_COL),
348
+ language="md",
349
+ )
350
+ return await okk.edit(
351
+ f"**• Ultroid Userbot •**{cli}", file=img, buttons=button
352
+ )
353
+ except Exception as er:
354
+ LOGS.exception(er)
355
+ changelog_str = changelog + cli
356
+ if len(changelog_str) > 1024:
357
+ await okk.edit(get_string("upd_4"))
358
+ await asyncio.sleep(2)
359
+ with open("ultroid_updates.txt", "w+") as file:
360
+ file.write(tl_chnglog)
361
+ await okk.edit(
362
+ get_string("upd_5"),
363
+ file="ultroid_updates.txt",
364
+ buttons=button,
365
+ )
366
+ remove("ultroid_updates.txt")
367
+ return
368
+ await okk.edit(
369
+ changelog_str,
370
+ buttons=button,
371
+ parse_mode="html",
372
+ )
373
+
374
+
375
+ @callback(
376
+ re.compile(
377
+ "pasta-(.*)",
378
+ ),
379
+ owner=True,
380
+ )
381
+ async def _(e):
382
+ ok = (e.data_match.group(1)).decode("UTF-8")
383
+ index = None
384
+ if "|" in ok:
385
+ ok, index = ok.split("|")
386
+ with open(ok, "r") as hmm:
387
+ _, data = await get_paste(hmm.read())
388
+ if not data.get("link"):
389
+ return await e.answer(key[:30], alert=True)
390
+ if not key.startswith("http"):
391
+ link, raw = data["link"], data["raw"]
392
+ else:
393
+ link = key
394
+ raw = f"{key}/raw"
395
+ if ok.startswith("addons"):
396
+ key = "Addons"
397
+ elif ok.startswith("vcbot"):
398
+ key = "VCBot"
399
+ else:
400
+ key = "Official"
401
+ data = f"uh_{key}_"
402
+ if index is not None:
403
+ data += f"|{index}"
404
+ await e.edit(
405
+ "",
406
+ buttons=[
407
+ [Button.url("Lɪɴᴋ", link), Button.url("Rᴀᴡ", raw)],
408
+ [Button.inline("« Bᴀᴄᴋ", data=data)],
409
+ ],
410
+ )
411
+
412
+
413
+ @callback(re.compile("cbs_(.*)"), owner=True)
414
+ async def _edit_to(event):
415
+ match = event.data_match.group(1).decode("utf-8")
416
+ data = _buttons.get(match)
417
+ if not data:
418
+ return
419
+ await event.edit(data["text"], buttons=data["buttons"], link_preview=False)
420
+
421
+
422
+ @callback(re.compile("abs_(.*)"), owner=True)
423
+ async def convo_handler(event: events.CallbackQuery):
424
+ match = event.data_match.group(1).decode("utf-8")
425
+ if not _convo.get(match):
426
+ return
427
+ await event.delete()
428
+ get_ = _convo[match]
429
+ back = get_["back"]
430
+ async with event.client.conversation(event.sender_id) as conv:
431
+ await conv.send_message(get_["text"])
432
+ response = await conv.get_response()
433
+ themssg = response.message
434
+ try:
435
+ themssg = ast.literal_eval(themssg)
436
+ except Exception:
437
+ pass
438
+ if themssg == "/cancel":
439
+ return await conv.send_message(
440
+ "Cancelled!!",
441
+ buttons=get_back_button(back),
442
+ )
443
+ await setit(event, get_["var"], themssg)
444
+ await conv.send_message(
445
+ f"{get_['name']} changed to `{themssg}`",
446
+ buttons=get_back_button(back),
447
+ )
448
+
449
+
450
+ @callback("authorise", owner=True)
451
+ async def _(e):
452
+ if not e.is_private:
453
+ return
454
+ url = GDrive._create_token_file()
455
+ await e.edit("Go to the below link and send the code!")
456
+ async with asst.conversation(e.sender_id) as conv:
457
+ await conv.send_message(url)
458
+ code = await conv.get_response()
459
+ if GDrive._create_token_file(code=code.text):
460
+ await conv.send_message(
461
+ "`Success!\nYou are all set to use Google Drive with Ultroid Userbot.`",
462
+ buttons=Button.inline("Main Menu", data="setter"),
463
+ )
464
+ else:
465
+ await conv.send_message("Wrong code! Click authorise again.")
466
+
467
+
468
+ @callback("folderid", owner=True, func=lambda x: x.is_private)
469
+ async def _(e):
470
+ if not e.is_private:
471
+ return
472
+ msg = (
473
+ "Send your FOLDER ID\n\n"
474
+ + "For FOLDER ID:\n"
475
+ + "1. Open Google Drive App.\n"
476
+ + "2. Create Folder.\n"
477
+ + "3. Make that folder public.\n"
478
+ + "4. Send link of that folder."
479
+ )
480
+ await e.delete()
481
+ async with asst.conversation(e.sender_id, timeout=150) as conv:
482
+ await conv.send_message(msg)
483
+ repl = await conv.get_response()
484
+ id = repl.text
485
+ if id.startswith("https"):
486
+ id = id.split("?id=")[-1]
487
+ udB.set_key("GDRIVE_FOLDER_ID", id)
488
+ await repl.reply(
489
+ "`Success.`",
490
+ buttons=get_back_button("gdrive"),
491
+ )
492
+
493
+
494
+ @callback("gdrive", owner=True)
495
+ async def _(e):
496
+ if not e.is_private:
497
+ return
498
+ await e.edit(
499
+ "Click Authorise and send the code.\n\nYou can use your own CLIENT ID and SECRET by [this](https://t.me/UltroidUpdates/37)",
500
+ buttons=[
501
+ [
502
+ Button.inline("Folder ID", data="folderid"),
503
+ Button.inline("Authorise", data="authorise"),
504
+ ],
505
+ [Button.inline("« Back", data="cbs_otvars")],
506
+ ],
507
+ link_preview=False,
508
+ )
509
+
510
+
511
+ @callback("dmof", owner=True)
512
+ async def rhwhe(e):
513
+ if udB.get_key("DUAL_MODE"):
514
+ udB.del_key("DUAL_MODE")
515
+ key = "Off"
516
+ else:
517
+ udB.set_key("DUAL_MODE", "True")
518
+ key = "On"
519
+ Msg = f"Dual Mode : {key}"
520
+ await e.edit(Msg, buttons=get_back_button("cbs_otvars"))
521
+
522
+
523
+ @callback("dmhn", owner=True)
524
+ async def hndlrr(event):
525
+ await event.delete()
526
+ pru = event.sender_id
527
+ var = "DUAL_HNDLR"
528
+ name = "Dual Handler"
529
+ CH = udB.get_key(var) or "/"
530
+ async with event.client.conversation(pru) as conv:
531
+ await conv.send_message(
532
+ f"Send The Symbol Which u want as Handler/Trigger to use your Assistant bot\nUr Current Handler is [ `{CH}` ]\n\n use /cancel to cancel.",
533
+ )
534
+ response = conv.wait_event(events.NewMessage(chats=pru))
535
+ response = await response
536
+ themssg = response.message.message
537
+ if themssg == "/cancel":
538
+ await conv.send_message(
539
+ "Cancelled!!",
540
+ buttons=get_back_button("cbs_otvars"),
541
+ )
542
+ elif len(themssg) > 1:
543
+ await conv.send_message(
544
+ "Incorrect Handler",
545
+ buttons=get_back_button("cbs_otvars"),
546
+ )
547
+ else:
548
+ await setit(event, var, themssg)
549
+ await conv.send_message(
550
+ f"{name} changed to {themssg}",
551
+ buttons=get_back_button("cbs_otvars"),
552
+ )
553
+
554
+
555
+ @callback("emoj", owner=True)
556
+ async def emoji(event):
557
+ await event.delete()
558
+ pru = event.sender_id
559
+ var = "EMOJI_IN_HELP"
560
+ name = f"Emoji in `{HNDLR}help` menu"
561
+ async with event.client.conversation(pru) as conv:
562
+ await conv.send_message("Send emoji u want to set 🙃.\n\nUse /cancel to cancel.")
563
+ response = conv.wait_event(events.NewMessage(chats=pru))
564
+ response = await response
565
+ themssg = response.message.message
566
+ if themssg == "/cancel":
567
+ await conv.send_message(
568
+ "Cancelled!!",
569
+ buttons=get_back_button("cbs_otvars"),
570
+ )
571
+ elif themssg.startswith(("/", HNDLR)):
572
+ await conv.send_message(
573
+ "Incorrect Emoji",
574
+ buttons=get_back_button("cbs_otvars"),
575
+ )
576
+ else:
577
+ await setit(event, var, themssg)
578
+ await conv.send_message(
579
+ f"{name} changed to {themssg}\n",
580
+ buttons=get_back_button("cbs_otvars"),
581
+ )
582
+
583
+
584
+ @callback("plg", owner=True)
585
+ async def pluginch(event):
586
+ await event.delete()
587
+ pru = event.sender_id
588
+ var = "PLUGIN_CHANNEL"
589
+ name = "Plugin Channel"
590
+ async with event.client.conversation(pru) as conv:
591
+ await conv.send_message(
592
+ "Send id or username of a channel from where u want to install all plugins\n\nOur Channel~ @ultroidplugins\n\nUse /cancel to cancel.",
593
+ )
594
+ response = conv.wait_event(events.NewMessage(chats=pru))
595
+ response = await response
596
+ themssg = response.message.message
597
+ if themssg == "/cancel":
598
+ await conv.send_message(
599
+ "Cancelled!!",
600
+ buttons=get_back_button("cbs_otvars"),
601
+ )
602
+ elif themssg.startswith(("/", HNDLR)):
603
+ await conv.send_message(
604
+ "Incorrect channel",
605
+ buttons=get_back_button("cbs_otvars"),
606
+ )
607
+ else:
608
+ await setit(event, var, themssg)
609
+ await conv.send_message(
610
+ f"{name} changed to {themssg}\n After Setting All Things Do Restart",
611
+ buttons=get_back_button("cbs_otvars"),
612
+ )
613
+
614
+
615
+ @callback("hhndlr", owner=True)
616
+ async def hndlrr(event):
617
+ await event.delete()
618
+ pru = event.sender_id
619
+ var = "HNDLR"
620
+ name = "Handler/ Trigger"
621
+ async with event.client.conversation(pru) as conv:
622
+ await conv.send_message(
623
+ f"Send The Symbol Which u want as Handler/Trigger to use bot\nUr Current Handler is [ `{HNDLR}` ]\n\n use /cancel to cancel.",
624
+ )
625
+ response = conv.wait_event(events.NewMessage(chats=pru))
626
+ response = await response
627
+ themssg = response.message.message
628
+ if themssg == "/cancel":
629
+ await conv.send_message(
630
+ "Cancelled!!",
631
+ buttons=get_back_button("cbs_otvars"),
632
+ )
633
+ elif len(themssg) > 1:
634
+ await conv.send_message(
635
+ "Incorrect Handler",
636
+ buttons=get_back_button("cbs_otvars"),
637
+ )
638
+ elif themssg.startswith(("/", "#", "@")):
639
+ await conv.send_message(
640
+ "This cannot be used as handler",
641
+ buttons=get_back_button("cbs_otvars"),
642
+ )
643
+ else:
644
+ await setit(event, var, themssg)
645
+ await conv.send_message(
646
+ f"{name} changed to {themssg}",
647
+ buttons=get_back_button("cbs_otvars"),
648
+ )
649
+
650
+
651
+ @callback("shndlr", owner=True)
652
+ async def hndlrr(event):
653
+ await event.delete()
654
+ pru = event.sender_id
655
+ var = "SUDO_HNDLR"
656
+ name = "Sudo Handler"
657
+ async with event.client.conversation(pru) as conv:
658
+ await conv.send_message(
659
+ "Send The Symbol Which u want as Sudo Handler/Trigger to use bot\n\n use /cancel to cancel."
660
+ )
661
+
662
+ response = conv.wait_event(events.NewMessage(chats=pru))
663
+ response = await response
664
+ themssg = response.message.message
665
+ if themssg == "/cancel":
666
+ await conv.send_message(
667
+ "Cancelled!!",
668
+ buttons=get_back_button("cbs_otvars"),
669
+ )
670
+ elif len(themssg) > 1:
671
+ await conv.send_message(
672
+ "Incorrect Handler",
673
+ buttons=get_back_button("cbs_otvars"),
674
+ )
675
+ elif themssg.startswith(("/", "#", "@")):
676
+ await conv.send_message(
677
+ "This cannot be used as handler",
678
+ buttons=get_back_button("cbs_otvars"),
679
+ )
680
+ else:
681
+ await setit(event, var, themssg)
682
+ await conv.send_message(
683
+ f"{name} changed to {themssg}",
684
+ buttons=get_back_button("cbs_otvars"),
685
+ )
686
+
687
+
688
+ @callback("taglog", owner=True)
689
+ async def tagloggrr(e):
690
+ BUTTON = [
691
+ [Button.inline("SET TAG LOG", data="abs_settag")],
692
+ [Button.inline("DELETE TAG LOG", data="deltag")],
693
+ get_back_button("cbs_otvars"),
694
+ ]
695
+ await e.edit(
696
+ "Choose Options",
697
+ buttons=BUTTON,
698
+ )
699
+
700
+
701
+ @callback("deltag", owner=True)
702
+ async def _(e):
703
+ udB.del_key("TAG_LOG")
704
+ await e.answer("Done!!! Tag Logger has been turned Off")
705
+
706
+
707
+ @callback("eaddon", owner=True)
708
+ async def pmset(event):
709
+ BT = (
710
+ [Button.inline("Aᴅᴅᴏɴs Oғғ", data="edof")]
711
+ if udB.get_key("ADDONS")
712
+ else [Button.inline("Aᴅᴅᴏɴs Oɴ", data="edon")]
713
+ )
714
+
715
+ await event.edit(
716
+ "ADDONS~ Extra Plugins:",
717
+ buttons=[
718
+ BT,
719
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")],
720
+ ],
721
+ )
722
+
723
+
724
+ @callback("edon", owner=True)
725
+ async def eddon(event):
726
+ var = "ADDONS"
727
+ await setit(event, var, "True")
728
+ await event.edit(
729
+ "Done! ADDONS has been turned on!!\n\n After Setting All Things Do Restart",
730
+ buttons=get_back_button("eaddon"),
731
+ )
732
+
733
+
734
+ @callback("edof", owner=True)
735
+ async def eddof(event):
736
+ udB.set_key("ADDONS", "False")
737
+ await event.edit(
738
+ "Done! ADDONS has been turned off!! After Setting All Things Do Restart",
739
+ buttons=get_back_button("eaddon"),
740
+ )
741
+
742
+
743
+ @callback("sudo", owner=True)
744
+ async def pmset(event):
745
+ BT = (
746
+ [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oғғ", data="ofsudo")]
747
+ if udB.get_key("SUDO")
748
+ else [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oɴ", data="onsudo")]
749
+ )
750
+
751
+ await event.edit(
752
+ f"SUDO MODE ~ Some peoples can use ur Bot which u selected. To know More use `{HNDLR}help sudo`",
753
+ buttons=[
754
+ BT,
755
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")],
756
+ ],
757
+ )
758
+
759
+
760
+ @callback("onsudo", owner=True)
761
+ async def eddon(event):
762
+ var = "SUDO"
763
+ await setit(event, var, "True")
764
+ await event.edit(
765
+ "Done! SUDO MODE has been turned on!!\n\n After Setting All Things Do Restart",
766
+ buttons=get_back_button("sudo"),
767
+ )
768
+
769
+
770
+ @callback("ofsudo", owner=True)
771
+ async def eddof(event):
772
+ var = "SUDO"
773
+ await setit(event, var, "False")
774
+ await event.edit(
775
+ "Done! SUDO MODE has been turned off!! After Setting All Things Do Restart",
776
+ buttons=get_back_button("sudo"),
777
+ )
778
+
779
+
780
+ @callback("sfgrp", owner=True)
781
+ async def sfgrp(event):
782
+ await event.delete()
783
+ name = "FBan Group ID"
784
+ var = "FBAN_GROUP_ID"
785
+ pru = event.sender_id
786
+ async with asst.conversation(pru) as conv:
787
+ await conv.send_message(
788
+ f"Make a group, add @MissRose_Bot, send `{HNDLR}id`, copy that and send it here.\nUse /cancel to go back.",
789
+ )
790
+ response = conv.wait_event(events.NewMessage(chats=pru))
791
+ response = await response
792
+ themssg = response.message.message
793
+ if themssg == "/cancel":
794
+ return await conv.send_message(
795
+ "Cancelled!!",
796
+ buttons=get_back_button("cbs_sfban"),
797
+ )
798
+ await setit(event, var, themssg)
799
+ await conv.send_message(
800
+ f"{name} changed to {themssg}",
801
+ buttons=get_back_button("cbs_sfban"),
802
+ )
803
+
804
+
805
+ @callback("alvmed", owner=True)
806
+ async def media(event):
807
+ await event.delete()
808
+ pru = event.sender_id
809
+ var = "ALIVE_PIC"
810
+ name = "Alive Media"
811
+ async with event.client.conversation(pru) as conv:
812
+ await conv.send_message(
813
+ "**Alive Media**\nSend me a pic/gif/media to set as alive media.\n\nUse /cancel to terminate the operation.",
814
+ )
815
+ response = await conv.get_response()
816
+ try:
817
+ themssg = response.message
818
+ if themssg == "/cancel":
819
+ return await conv.send_message(
820
+ "Operation cancelled!!",
821
+ buttons=get_back_button("cbs_alvcstm"),
822
+ )
823
+ except BaseException as er:
824
+ LOGS.exception(er)
825
+ if (
826
+ not (response.text).startswith("/")
827
+ and response.text != ""
828
+ and (not response.media or isinstance(response.media, MessageMediaWebPage))
829
+ ):
830
+ url = text_to_url(response)
831
+ elif response.sticker:
832
+ url = response.file.id
833
+ else:
834
+ media = await event.client.download_media(response, "alvpc")
835
+ try:
836
+ url = uploader.upload_file(media)
837
+ remove(media)
838
+ except BaseException as er:
839
+ LOGS.exception(er)
840
+ return await conv.send_message(
841
+ "Terminated.",
842
+ buttons=get_back_button("cbs_alvcstm"),
843
+ )
844
+ await setit(event, var, url)
845
+ await conv.send_message(
846
+ f"{name} has been set.",
847
+ buttons=get_back_button("cbs_alvcstm"),
848
+ )
849
+
850
+
851
+ @callback("delmed", owner=True)
852
+ async def dell(event):
853
+ try:
854
+ udB.del_key("ALIVE_PIC")
855
+ return await event.edit(
856
+ get_string("clst_5"), buttons=get_back_button("cbs_alabs_vcstm")
857
+ )
858
+ except BaseException as er:
859
+ LOGS.exception(er)
860
+ return await event.edit(
861
+ get_string("clst_4"),
862
+ buttons=get_back_button("cbs_alabs_vcstm"),
863
+ )
864
+
865
+
866
+ @callback("inpm_in", owner=True)
867
+ async def inl_on(event):
868
+ var = "INLINE_PM"
869
+ await setit(event, var, "True")
870
+ await event.edit(
871
+ "Done!! PMPermit type has been set to inline!",
872
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]],
873
+ )
874
+
875
+
876
+ @callback("inpm_no", owner=True)
877
+ async def inl_on(event):
878
+ var = "INLINE_PM"
879
+ await setit(event, var, "False")
880
+ await event.edit(
881
+ "Done!! PMPermit type has been set to normal!",
882
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]],
883
+ )
884
+
885
+
886
+ @callback("pmtxt", owner=True)
887
+ async def name(event):
888
+ await event.delete()
889
+ pru = event.sender_id
890
+ var = "PM_TEXT"
891
+ name = "PM Text"
892
+ async with event.client.conversation(pru) as conv:
893
+ await conv.send_message(
894
+ "**PM Text**\nEnter the new Pmpermit text.\n\nu can use `{name}` `{fullname}` `{count}` `{mention}` `{username}` to get this from user Too\n\nUse /cancel to terminate the operation.",
895
+ )
896
+ response = conv.wait_event(events.NewMessage(chats=pru))
897
+ response = await response
898
+ themssg = response.message.message
899
+ if themssg == "/cancel":
900
+ return await conv.send_message(
901
+ "Cancelled!!",
902
+ buttons=get_back_button("cbs_pmcstm"),
903
+ )
904
+ if len(themssg) > 4090:
905
+ return await conv.send_message(
906
+ "Message too long!\nGive a shorter message please!!",
907
+ buttons=get_back_button("cbs_pmcstm"),
908
+ )
909
+ await setit(event, var, themssg)
910
+ await conv.send_message(
911
+ f"{name} changed to {themssg}\n\nAfter Setting All Things Do restart",
912
+ buttons=get_back_button("cbs_pmcstm"),
913
+ )
914
+
915
+
916
+ @callback("swarn", owner=True)
917
+ async def name(event):
918
+ m = range(1, 10)
919
+ tultd = [Button.inline(f"{x}", data=f"wrns_{x}") for x in m]
920
+ lst = list(zip(tultd[::3], tultd[1::3], tultd[2::3]))
921
+ lst.append([Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")])
922
+ await event.edit(
923
+ "Select the number of warnings for a user before getting blocked in PMs.",
924
+ buttons=lst,
925
+ )
926
+
927
+
928
+ @callback(re.compile(b"wrns_(.*)"), owner=True)
929
+ async def set_wrns(event):
930
+ value = int(event.data_match.group(1).decode("UTF-8"))
931
+ if dn := udB.set_key("PMWARNS", value):
932
+ await event.edit(
933
+ f"PM Warns Set to {value}.\nNew users will have {value} chances in PMs before getting banned.",
934
+ buttons=get_back_button("cbs_pmcstm"),
935
+ )
936
+ else:
937
+ await event.edit(
938
+ f"Something went wrong, please check your {HNDLR}logs!",
939
+ buttons=get_back_button("cbs_pmcstm"),
940
+ )
941
+
942
+
943
+ @callback("pmmed", owner=True)
944
+ async def media(event):
945
+ await event.delete()
946
+ pru = event.sender_id
947
+ var = "PMPIC"
948
+ name = "PM Media"
949
+ async with event.client.conversation(pru) as conv:
950
+ await conv.send_message(
951
+ "**PM Media**\nSend me a pic/gif/sticker/link to set as pmpermit media.\n\nUse /cancel to terminate the operation.",
952
+ )
953
+ response = await conv.get_response()
954
+ try:
955
+ themssg = response.message
956
+ if themssg == "/cancel":
957
+ return await conv.send_message(
958
+ "Operation cancelled!!",
959
+ buttons=get_back_button("cbs_pmcstm"),
960
+ )
961
+ except BaseException as er:
962
+ LOGS.exception(er)
963
+ media = await event.client.download_media(response, "pmpc")
964
+ if (
965
+ not (response.text).startswith("/")
966
+ and response.text != ""
967
+ and (not response.media or isinstance(response.media, MessageMediaWebPage))
968
+ ):
969
+ url = text_to_url(response)
970
+ elif response.sticker:
971
+ url = response.file.id
972
+ else:
973
+ try:
974
+ url = uploader.upload_file(media)
975
+ remove(media)
976
+ except BaseException as er:
977
+ LOGS.exception(er)
978
+ return await conv.send_message(
979
+ "Terminated.",
980
+ buttons=get_back_button("cbs_pmcstm"),
981
+ )
982
+ await setit(event, var, url)
983
+ await conv.send_message(
984
+ f"{name} has been set.",
985
+ buttons=get_back_button("cbs_pmcstm"),
986
+ )
987
+
988
+
989
+ @callback("delpmmed", owner=True)
990
+ async def dell(event):
991
+ try:
992
+ udB.del_key("PMPIC")
993
+ return await event.edit(
994
+ get_string("clst_5"), buttons=get_back_button("cbs_pmcstm")
995
+ )
996
+ except BaseException as er:
997
+ LOGS.exception(er)
998
+ return await event.edit(
999
+ get_string("clst_4"),
1000
+ buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]],
1001
+ )
1002
+
1003
+
1004
+ @callback("apon", owner=True)
1005
+ async def apon(event):
1006
+ var = "AUTOAPPROVE"
1007
+ await setit(event, var, "True")
1008
+ await event.edit(
1009
+ "Done!! AUTOAPPROVE Started!!",
1010
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]],
1011
+ )
1012
+
1013
+
1014
+ @callback("apof", owner=True)
1015
+ async def apof(event):
1016
+ try:
1017
+ udB.set_key("AUTOAPPROVE", "False")
1018
+ return await event.edit(
1019
+ "Done! AUTOAPPROVE Stopped!!",
1020
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]],
1021
+ )
1022
+ except BaseException as er:
1023
+ LOGS.exception(er)
1024
+ return await event.edit(
1025
+ get_string("clst_4"),
1026
+ buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]],
1027
+ )
1028
+
1029
+
1030
+ @callback("pml", owner=True)
1031
+ async def l_vcs(event):
1032
+ BT = (
1033
+ [Button.inline("PMLOGGER OFF", data="pmlogof")]
1034
+ if udB.get_key("PMLOG")
1035
+ else [Button.inline("PMLOGGER ON", data="pmlog")]
1036
+ )
1037
+
1038
+ await event.edit(
1039
+ "PMLOGGER This Will Forward Ur Pm to Ur Private Group -",
1040
+ buttons=[
1041
+ BT,
1042
+ [Button.inline("PᴍLᴏɢɢᴇʀ Gʀᴏᴜᴘ", "abs_pmlgg")],
1043
+ [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")],
1044
+ ],
1045
+ )
1046
+
1047
+
1048
+ @callback("pmlog", owner=True)
1049
+ async def pmlog(event):
1050
+ await setit(event, "PMLOG", "True")
1051
+ await event.edit(
1052
+ "Done!! PMLOGGER Started!!",
1053
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]],
1054
+ )
1055
+
1056
+
1057
+ @callback("pmlogof", owner=True)
1058
+ async def pmlogof(event):
1059
+ try:
1060
+ udB.del_key("PMLOG")
1061
+ return await event.edit(
1062
+ "Done! PMLOGGER Stopped!!",
1063
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]],
1064
+ )
1065
+ except BaseException as er:
1066
+ LOGS.exception(er)
1067
+ return await event.edit(
1068
+ get_string("clst_4"),
1069
+ buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]],
1070
+ )
1071
+
1072
+
1073
+ @callback("pmon", owner=True)
1074
+ async def pmonn(event):
1075
+ var = "PMSETTING"
1076
+ await setit(event, var, "True")
1077
+ await event.edit(
1078
+ "Done! PMPermit has been turned on!!",
1079
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]],
1080
+ )
1081
+
1082
+
1083
+ @callback("pmoff", owner=True)
1084
+ async def pmofff(event):
1085
+ var = "PMSETTING"
1086
+ await setit(event, var, "False")
1087
+ await event.edit(
1088
+ "Done! PMPermit has been turned off!!",
1089
+ buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]],
1090
+ )
1091
+
1092
+
1093
+ @callback("botmew", owner=True)
1094
+ async def hhh(e):
1095
+ async with e.client.conversation(e.chat_id) as conv:
1096
+ await conv.send_message("Send Any Media to keep at your Bot's welcome ")
1097
+ msg = await conv.get_response()
1098
+ if not msg.media or msg.text.startswith("/"):
1099
+ return await conv.send_message(
1100
+ "Terminated!", buttons=get_back_button("cbs_chatbot")
1101
+ )
1102
+ udB.set_key("STARTMEDIA", msg.file.id)
1103
+ await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot"))
1104
+
1105
+
1106
+ @callback("botinfe", owner=True)
1107
+ async def hhh(e):
1108
+ async with e.client.conversation(e.chat_id) as conv:
1109
+ await conv.send_message(
1110
+ "Send message to set to Display, when user Press Info button in Bot Welcome!\n\nsend `False` to completely remove that button.."
1111
+ )
1112
+ msg = await conv.get_response()
1113
+ if msg.media or msg.text.startswith("/"):
1114
+ return await conv.send_message(
1115
+ "Terminated!", buttons=get_back_button("cbs_chatbot")
1116
+ )
1117
+ udB.set_key("BOT_INFO_START", msg.text)
1118
+ await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot"))
1119
+
1120
+
1121
+ @callback("pmfs", owner=True)
1122
+ async def heheh(event):
1123
+ Ll = []
1124
+ err = ""
1125
+ async with event.client.conversation(event.chat_id) as conv:
1126
+ await conv.send_message(
1127
+ "• Send The Chat Id(s), which you want user to Join Before using Chat/Pm Bot\n\n• Send /clear to disable PmBot Force sub..\n• • Send /cancel to stop this process.."
1128
+ )
1129
+ await conv.send_message(
1130
+ "Example : \n`-1001234567\n-100778888`\n\nFor Multiple Chat(s)."
1131
+ )
1132
+ try:
1133
+ msg = await conv.get_response()
1134
+ except AsyncTimeOut:
1135
+ return await conv.send_message("**• TimeUp!**\nStart from /start back.")
1136
+ if not msg.text or msg.text.startswith("/"):
1137
+ timyork = "Cancelled!"
1138
+ if msg.text == "/clear":
1139
+ udB.del_key("PMBOT_FSUB")
1140
+ timyork = "Done! Force Subscribe Stopped\nRestart your Bot!"
1141
+ return await conv.send_message(
1142
+ "Cancelled!", buttons=get_back_button("cbs_chatbot")
1143
+ )
1144
+ for chat in msg.message.split("\n"):
1145
+ if chat.startswith("-") or chat.isdigit():
1146
+ chat = int(chat)
1147
+ try:
1148
+ CHSJSHS = await event.client.get_entity(chat)
1149
+ Ll.append(get_peer_id(CHSJSHS))
1150
+ except Exception as er:
1151
+ err += f"**{chat}** : {er}\n"
1152
+ if err:
1153
+ return await conv.send_message(err)
1154
+ udB.set_key("PMBOT_FSUB", str(Ll))
1155
+ await conv.send_message(
1156
+ "Done!\nRestart Your Bot.", buttons=get_back_button("cbs_chatbot")
1157
+ )
1158
+
1159
+
1160
+ @callback("bwel", owner=True)
1161
+ async def name(event):
1162
+ await event.delete()
1163
+ pru = event.sender_id
1164
+ var = "STARTMSG"
1165
+ name = "Bot Welcome Message:"
1166
+ async with event.client.conversation(pru) as conv:
1167
+ await conv.send_message(
1168
+ "**BOT WELCOME MSG**\nEnter the msg which u want to show when someone start your assistant Bot.\nYou Can use `{me}` , `{mention}` Parameters Too\nUse /cancel to terminate the operation.",
1169
+ )
1170
+ response = conv.wait_event(events.NewMessage(chats=pru))
1171
+ response = await response
1172
+ themssg = response.message.message
1173
+ if themssg == "/cancel":
1174
+ return await conv.send_message(
1175
+ "Cancelled!!",
1176
+ buttons=get_back_button("cbs_chatbot"),
1177
+ )
1178
+ await setit(event, var, themssg)
1179
+ await conv.send_message(
1180
+ f"{name} changed to {themssg}",
1181
+ buttons=get_back_button("cbs_chatbot"),
1182
+ )
1183
+
1184
+
1185
+ @callback("onchbot", owner=True)
1186
+ async def chon(event):
1187
+ var = "PMBOT"
1188
+ await setit(event, var, "True")
1189
+ Loader(path="assistant/pmbot.py", key="PM Bot").load()
1190
+ if AST_PLUGINS.get("pmbot"):
1191
+ for i, e in AST_PLUGINS["pmbot"]:
1192
+ event.client.remove_event_handler(i)
1193
+ for i, e in AST_PLUGINS["pmbot"]:
1194
+ event.client.add_event_handler(i, events.NewMessage(**e))
1195
+ await event.edit(
1196
+ "Done! Now u Can Chat With People Via This Bot",
1197
+ buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")],
1198
+ )
1199
+
1200
+
1201
+ @callback("ofchbot", owner=True)
1202
+ async def chon(event):
1203
+ var = "PMBOT"
1204
+ await setit(event, var, "False")
1205
+ if AST_PLUGINS.get("pmbot"):
1206
+ for i, e in AST_PLUGINS["pmbot"]:
1207
+ event.client.remove_event_handler(i)
1208
+ await event.edit(
1209
+ "Done! Chat People Via This Bot Stopped.",
1210
+ buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")],
1211
+ )
1212
+
1213
+
1214
+ @callback("inli_pic", owner=True)
1215
+ async def media(event):
1216
+ await event.delete()
1217
+ pru = event.sender_id
1218
+ var = "INLINE_PIC"
1219
+ name = "Inline Media"
1220
+ async with event.client.conversation(pru) as conv:
1221
+ await conv.send_message(
1222
+ "**Inline Media**\nSend me a pic/gif/ or link to set as inline media.\n\nUse /cancel to terminate the operation.",
1223
+ )
1224
+ response = await conv.get_response()
1225
+ try:
1226
+ themssg = response.message
1227
+ if themssg == "/cancel":
1228
+ return await conv.send_message(
1229
+ "Operation cancelled!!",
1230
+ buttons=get_back_button("setter"),
1231
+ )
1232
+ except BaseException as er:
1233
+ LOGS.exception(er)
1234
+ media = await event.client.download_media(response, "inlpic")
1235
+ if (
1236
+ not (response.text).startswith("/")
1237
+ and response.text != ""
1238
+ and (not response.media or isinstance(response.media, MessageMediaWebPage))
1239
+ ):
1240
+ url = text_to_url(response)
1241
+ else:
1242
+ try:
1243
+ url = uploader.upload_file(media)
1244
+ remove(media)
1245
+ except BaseException as er:
1246
+ LOGS.exception(er)
1247
+ return await conv.send_message(
1248
+ "Terminated.",
1249
+ buttons=get_back_button("setter"),
1250
+ )
1251
+ await setit(event, var, url)
1252
+ await conv.send_message(
1253
+ f"{name} has been set.",
1254
+ buttons=get_back_button("setter"),
1255
+ )
1256
+
1257
+
1258
+ FD_MEDIA = {}
1259
+
1260
+
1261
+ @callback(re.compile("fd(.*)"), owner=True)
1262
+ async def fdroid_dler(event):
1263
+ uri = event.data_match.group(1).decode("utf-8")
1264
+ if FD_MEDIA.get(uri):
1265
+ return await event.edit(file=FD_MEDIA[uri])
1266
+ await event.answer("• Starting Download •", alert=True)
1267
+ await event.edit("• Downloading.. •")
1268
+ URL = f"https://f-droid.org/packages/{uri}"
1269
+ conte = await async_searcher(URL, re_content=True)
1270
+ BSC = bs(conte, "html.parser", from_encoding="utf-8")
1271
+ dl_ = BSC.find("p", "package-version-download").find("a")["href"]
1272
+ title = BSC.find("h3", "package-name").text.strip()
1273
+ thumb = BSC.find("img", "package-icon")["src"]
1274
+ if thumb.startswith("/"):
1275
+ thumb = f"https://f-droid.org{thumb}"
1276
+ thumb, _ = await fast_download(thumb, filename=f"{uri}.png")
1277
+ s_time = time.time()
1278
+ file, _ = await fast_download(
1279
+ dl_,
1280
+ filename=f"{title}.apk",
1281
+ progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
1282
+ progress(
1283
+ d,
1284
+ t,
1285
+ event,
1286
+ s_time,
1287
+ "Downloading...",
1288
+ )
1289
+ ),
1290
+ )
1291
+
1292
+ time.time()
1293
+ n_file = await event.client.fast_uploader(
1294
+ file, show_progress=True, event=event, message="Uploading...", to_delete=True
1295
+ )
1296
+ buttons = Button.switch_inline("Search Back", query="fdroid", same_peer=True)
1297
+ try:
1298
+ msg = await event.edit(
1299
+ f"**• [{title}]({URL}) •**", file=n_file, thumb=thumb, buttons=buttons
1300
+ )
1301
+ except Exception as er:
1302
+ LOGS.exception(er)
1303
+ try:
1304
+ msg = await event.client.edit_message(
1305
+ await event.get_input_chat(),
1306
+ event.message_id,
1307
+ f"**• [{title}]({URL}) •**",
1308
+ buttons=buttons,
1309
+ thumb=thumb,
1310
+ file=n_file,
1311
+ )
1312
+ except Exception as er:
1313
+ os.remove(thumb)
1314
+ LOGS.exception(er)
1315
+ return await event.edit(f"**ERROR**: `{er}`", buttons=buttons)
1316
+ if msg and hasattr(msg, "media"):
1317
+ FD_MEDIA.update({uri: msg.media})
1318
+ os.remove(thumb)
assistant/games.py ADDED
@@ -0,0 +1,331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ • `{i}akinator` | `/akinator`
10
+ Start akinator game from Userbot/Assistant
11
+
12
+ • `/startgame`
13
+ Open Portal for Games
14
+ """
15
+
16
+ import asyncio
17
+ import re, uuid, operator
18
+ from random import choice, shuffle
19
+
20
+ from akipy.async_akipy import Akinator
21
+ from telethon.errors.rpcerrorlist import BotMethodInvalidError
22
+ from telethon.events import Raw
23
+ from telethon.tl.types import InputMediaPoll, Poll, PollAnswer, UpdateMessagePollVote
24
+
25
+ from pyUltroid._misc._decorators import ultroid_cmd
26
+ from logging import getLogger
27
+ from html import unescape
28
+ from telethon.tl.types import TextWithEntities
29
+ from pyUltroid.fns.helper import inline_mention
30
+ from pyUltroid.fns.tools import async_searcher
31
+ from telethon.errors import ChatSendStickersForbiddenError
32
+
33
+ from . import * # Ensure this import matches your project structure
34
+
35
+ games = {}
36
+ aki_photo = "https://graph.org/file/3cc8825c029fd0cab9edc.jpg"
37
+
38
+ akipyLOGS = getLogger("akipy")
39
+
40
+ @ultroid_cmd(pattern="akinator")
41
+ async def akina(e):
42
+ sta = Akinator()
43
+ games[e.chat_id] = {e.id: sta}
44
+ LOGS.info(f"Game started for chat {e.chat_id} with ID {e.id}.")
45
+ try:
46
+ m = await e.client.inline_query(asst.me.username, f"aki_{e.chat_id}_{e.id}")
47
+ await m[0].click(e.chat_id)
48
+ akipyLOGS.info(f"Clicked inline result for chat {e.chat_id}")
49
+ except BotMethodInvalidError as err:
50
+ akipyLOGS.error(f"BotMethodInvalidError: {err}")
51
+ await asst.send_file(
52
+ e.chat_id,
53
+ aki_photo,
54
+ buttons=Button.inline(get_string("aki_2"), data=f"aki_{e.chat_id}_{e.id}"),
55
+ )
56
+ except Exception as er:
57
+ akipyLOGS.error(f"Unexpected error: {er}")
58
+ return await e.eor(f"ERROR : {er}")
59
+ if e.out:
60
+ await e.delete()
61
+
62
+
63
+ @asst_cmd(pattern="akinator", owner=True)
64
+ async def _akokk(e):
65
+ await akina(e)
66
+
67
+
68
+ @callback(re.compile("aki_(.*)"), owner=True)
69
+ async def doai(e):
70
+ adt = e.pattern_match.group(1).strip().decode("utf-8")
71
+ dt = adt.split("_")
72
+ ch = int(dt[0])
73
+ mid = int(dt[1])
74
+ await e.edit(get_string("com_1"))
75
+ try:
76
+ await games[ch][mid].start_game(child_mode=False)
77
+ bts = [Button.inline(o, f"aka_{adt}_{o}") for o in ["Yes", "No", "Idk"]]
78
+ cts = [Button.inline(o, f"aka_{adt}_{o}") for o in ["Probably", "Probably Not"]]
79
+ bts = [bts, cts]
80
+ await e.edit(f"Q. {games[ch][mid].question}", buttons=bts)
81
+ except KeyError:
82
+ return await e.answer(get_string("aki_1"), alert=True)
83
+
84
+
85
+ @callback(re.compile("aka_(.*)"), owner=True)
86
+ async def okah(e):
87
+ try:
88
+ mk = e.pattern_match.group(1).decode("utf-8").split("_")
89
+ #akipyLOGS.info(f"Parsed values: {mk}")
90
+
91
+ if len(mk) < 3:
92
+ akipyLOGS.error("Pattern match did not return enough parts.")
93
+ return await e.answer("Invalid data received.", alert=True)
94
+
95
+ ch = int(mk[0])
96
+ mid = int(mk[1])
97
+ ans = mk[2]
98
+
99
+ gm = games[ch][mid]
100
+ await gm.answer(ans)
101
+
102
+ # Check for the final guess in the API response
103
+ if gm.name_proposition and gm.description_proposition:
104
+ gm.win = True
105
+ text = f"It's {gm.name_proposition}\n{gm.description_proposition}"
106
+ await e.edit(text, file=gm.photo)
107
+ else:
108
+ # Game is not won yet, continue asking questions
109
+ buttons = [
110
+ [Button.inline(o, f"aka_{ch}_{mid}_{o}") for o in ["Yes", "No", "Idk"]],
111
+ [Button.inline(o, f"aka_{ch}_{mid}_{o}") for o in ["Probably", "Probably Not"]],
112
+ ]
113
+ await e.edit(gm.question, buttons=buttons)
114
+
115
+ except KeyError:
116
+ await e.answer(get_string("aki_3"))
117
+ except Exception as ex:
118
+ akipyLOGS.error(f"An unexpected error occurred: {ex}")
119
+
120
+
121
+ @in_pattern(re.compile("aki_?(.*)"), owner=True)
122
+ async def eiagx(e):
123
+ bts = Button.inline(get_string("aki_2"), data=e.text)
124
+ ci = types.InputWebDocument(aki_photo, 0, "image/jpeg", [])
125
+ ans = [
126
+ await e.builder.article(
127
+ "Akinator",
128
+ type="photo",
129
+ content=ci,
130
+ text="Akinator",
131
+ thumb=ci,
132
+ buttons=bts,
133
+ include_media=True,
134
+ )
135
+ ]
136
+ await e.answer(ans)
137
+
138
+
139
+ # ----------------------- Main Command ------------------- #
140
+
141
+ GIMAGE = "https://graph.org/file/1c51015bae5205a65fd69.jpg"
142
+
143
+ @asst_cmd(pattern="startgame", owner=True)
144
+ async def magic(event):
145
+ buttons = [
146
+ [Button.inline("Trivia Quiz", "trzia")],
147
+ [Button.inline("Cancel ❌", "delit")],
148
+ ]
149
+ await event.reply(
150
+ get_string("games_1"),
151
+ file=GIMAGE,
152
+ buttons=buttons,
153
+ )
154
+
155
+
156
+ # -------------------------- Trivia ----------------------- #
157
+
158
+ TR_BTS = {}
159
+ DIFI_KEYS = ["Easy", "Medium", "Hard"]
160
+ TRIVIA_CHATS = {}
161
+ POLLS = {}
162
+ CONGO_STICKER = [
163
+ "CAADAgADSgIAAladvQrJasZoYBh68AI",
164
+ "CAADAgADXhIAAuyZKUl879mlR_dkOwI",
165
+ "CAADAgADpQAD9wLID-xfZCDwOI5LAg",
166
+ "CAADAgADjAADECECEFZM-SrKO9GgAg",
167
+ "CAADAgADSwIAAj-VzArAzNCDiGWAHAI",
168
+ "CAADAgADhQADwZxgDIuMHR9IU10iAg",
169
+ "CAADAgADiwMAAsSraAuoe2BwYu1sdQI",
170
+ ]
171
+
172
+
173
+ @callback("delit", owner=True)
174
+ async def delete_it(event):
175
+ await event.delete()
176
+
177
+
178
+ @callback(re.compile("ctdown(.*)"), owner=True)
179
+ async def ct_spam(e):
180
+ n = e.data_match.group(1).decode("utf-8")
181
+ await e.answer(f"Wait {n} seconds..", alert=True)
182
+
183
+
184
+ @callback(re.compile("trzia(.*)"), owner=True)
185
+ async def choose_cata(event):
186
+ match = event.data_match.group(1).decode("utf-8")
187
+ if not match:
188
+ if TR_BTS.get("category"):
189
+ buttons = TR_BTS["category"]
190
+ else:
191
+ req = (
192
+ await async_searcher(
193
+ "https://opentdb.com/api_category.php", re_json=True
194
+ )
195
+ )["trivia_categories"]
196
+ btt = []
197
+ for i in req:
198
+ name = i["name"]
199
+ if ":" in name:
200
+ name = name.split(":")[1]
201
+ btt.append(Button.inline(name, f"trziad_{i['id']}"))
202
+ buttons = list(zip(btt[::2], btt[1::2]))
203
+ if len(btt) % 2 == 1:
204
+ buttons.append((btt[-1],))
205
+ buttons.append([Button.inline("Cancel ❌", "delit")])
206
+ TR_BTS.update({"category": buttons})
207
+ text = get_string("games_2")
208
+ elif match[0] == "d":
209
+ cat = match[1:]
210
+ buttons = [[Button.inline(i, f"trziac{cat}_{i}") for i in DIFI_KEYS]]
211
+ buttons.append(get_back_button("trzia"))
212
+ text = get_string("games_3")
213
+ elif match[0] == "c":
214
+ m = match[1:]
215
+ buttons = [[Button.inline(str(i), f"trziat{m}_{i}") for i in range(10, 70, 20)]]
216
+ text = get_string("games_4")
217
+ elif match[0] == "t":
218
+ m_ = match[1:]
219
+ buttons = [
220
+ [Button.inline(str(i), f"trzias{m_}_{i}") for i in [10, 30, 60, 120]]
221
+ ]
222
+ text = get_string("games_5")
223
+ elif match[0] == "s":
224
+ chat = event.chat_id
225
+ cat, le, nu, in_ = match[2:].split("_")
226
+ msg = await event.edit(get_string("games_6").format(le, nu))
227
+ for i in reversed(range(5)):
228
+ msg = await msg.edit(buttons=Button.inline(f"{i} ⏰", f"ctdown{i}"))
229
+ await asyncio.sleep(1)
230
+ await msg.edit(
231
+ msg.text + "\n\n• Send /cancel to stop the Quiz...", buttons=None
232
+ )
233
+ qsss = await async_searcher(
234
+ f"https://opentdb.com/api.php?amount={nu}&category={cat}&difficulty={le.lower()}",
235
+ re_json=True,
236
+ )
237
+ qs = qsss["results"]
238
+ if not qs:
239
+ await event.respond("Sorry, No Question Found for the given Criteria..")
240
+ await event.delete()
241
+ return
242
+ TRIVIA_CHATS.update({chat: {}})
243
+ for copper, q in enumerate(qs):
244
+ if TRIVIA_CHATS[chat].get("cancel") is not None:
245
+ break
246
+ ansi = str(uuid.uuid1()).split("-")[0].encode()
247
+ opts = [PollAnswer(TextWithEntities(unescape(q["correct_answer"]), entities=[]), ansi)]
248
+ [
249
+ opts.append(
250
+ PollAnswer(TextWithEntities(unescape(a), entities=[]), str(uuid.uuid1()).split("-")[0].encode())
251
+ )
252
+ for a in q["incorrect_answers"]
253
+ ]
254
+ shuffle(opts)
255
+ poll = InputMediaPoll(
256
+ Poll(
257
+ 0,
258
+ TextWithEntities(
259
+ f"[{copper+1}]. " + unescape(q["question"]),
260
+ entities=[]
261
+ ),
262
+ answers=opts,
263
+ public_voters=True,
264
+ quiz=True,
265
+ close_period=int(in_),
266
+ ),
267
+ correct_answers=[ansi],
268
+ solution="Join @TeamUltroid",
269
+ solution_entities=[],
270
+ )
271
+ m_ = await event.client.send_message(chat, file=poll)
272
+ POLLS.update({m_.poll.poll.id: {"chat": m_.chat_id, "answer": ansi}})
273
+ await asyncio.sleep(int(in_))
274
+ if not TRIVIA_CHATS[chat]:
275
+ await event.respond(
276
+ "No-One Got Any Score in the Quiz!\nBetter Luck Next Time!"
277
+ )
278
+ else:
279
+ try:
280
+ await event.respond(file=choice(CONGO_STICKER))
281
+ except ChatSendStickersForbiddenError:
282
+ pass
283
+ LBD = "🎯 **Scoreboard of the Quiz.**\n\n"
284
+ TRC = TRIVIA_CHATS[chat]
285
+ if "cancel" in TRC.keys():
286
+ del TRC["cancel"]
287
+ for userid, user_score in dict(
288
+ sorted(TRC.items(), key=operator.itemgetter(1), reverse=True)
289
+ ).items():
290
+ user = inline_mention(await event.client.get_entity(userid))
291
+ LBD += f"••• {user} - {user_score}\n"
292
+ await event.respond(LBD)
293
+ del TRIVIA_CHATS[chat]
294
+ list_ = list(POLLS.copy().keys())
295
+ for key in list_:
296
+ if POLLS[key]["chat"] == chat:
297
+ del POLLS[key]
298
+ return
299
+ await event.edit(text, buttons=buttons)
300
+
301
+
302
+ @asst.on(
303
+ Raw(UpdateMessagePollVote, func=lambda x: TRIVIA_CHATS and POLLS.get(x.poll_id))
304
+ )
305
+ async def pollish(eve: UpdateMessagePollVote):
306
+ if POLLS.get(eve.poll_id)["chat"] not in TRIVIA_CHATS.keys():
307
+ return
308
+ if not eve.options:
309
+ # Consider as correct answer if no options selected
310
+ chat = POLLS.get(eve.poll_id)["chat"]
311
+ user = eve.peer.user_id
312
+ if not TRIVIA_CHATS.get(chat, {}).get(user):
313
+ TRIVIA_CHATS[chat][user] = 1
314
+ else:
315
+ TRIVIA_CHATS[chat][user] += 1
316
+ return
317
+ if POLLS[eve.poll_id]["answer"] != eve.options[0]:
318
+ return
319
+ chat = POLLS.get(eve.poll_id)["chat"]
320
+ user = eve.peer.user_id
321
+ if not TRIVIA_CHATS.get(chat, {}).get(user):
322
+ TRIVIA_CHATS[chat][user] = 1
323
+ else:
324
+ TRIVIA_CHATS[chat][user] += 1
325
+
326
+
327
+ @asst_cmd("cancel", owner=True, func=lambda x: TRIVIA_CHATS.get(x.chat_id))
328
+ async def cancelish(event):
329
+ chat = TRIVIA_CHATS.get(event.chat_id)
330
+ chat.update({"cancel": True})
331
+ await event.respond("Cancelled!")
assistant/initial.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 . import *
11
+
12
+ STRINGS = {
13
+ 1: """🎇 **Thanks for Deploying Ultroid Userbot!**
14
+
15
+ • Here, are the Some Basic stuff from, where you can Know, about its Usage.""",
16
+ 2: """🎉** About Ultroid**
17
+
18
+ 🧿 Ultroid is Pluggable and powerful Telethon Userbot, made in Python from Scratch. It is Aimed to Increase Security along with Addition of Other Useful Features.
19
+
20
+ ❣ Made by **@TeamUltroid**""",
21
+ 3: """**💡• FAQs •**
22
+
23
+ -> [Username Tracker](https://t.me/UltroidUpdates/24)
24
+ -> [Keeping Custom Addons Repo](https://t.me/UltroidUpdates/28)
25
+ -> [Disabling Deploy message](https://t.me/UltroidUpdates/27)
26
+ -> [Setting up TimeZone](https://t.me/UltroidUpdates/22)
27
+ -> [About Inline PmPermit](https://t.me/UltroidUpdates/21)
28
+ -> [About Dual Mode](https://t.me/UltroidUpdates/18)
29
+ -> [Custom Thumbnail](https://t.me/UltroidUpdates/13)
30
+ -> [About FullSudo](https://t.me/UltroidUpdates/11)
31
+ -> [Setting Up PmBot](https://t.me/UltroidUpdates/2)
32
+ -> [Also Check](https://t.me/UltroidUpdates/14)
33
+
34
+ **• To Know About Updates**
35
+ - Join @TeamUltroid.""",
36
+ 4: f"""• `To Know All Available Commands`
37
+
38
+ - `{HNDLR}help`
39
+ - `{HNDLR}cmds`""",
40
+ 5: """• **For Any Other Query or Suggestion**
41
+ - Move to **@UltroidSupportChat**.
42
+
43
+ • Thanks for Reaching till END.""",
44
+ }
45
+
46
+
47
+ @callback(re.compile("initft_(\\d+)"))
48
+ async def init_depl(e):
49
+ CURRENT = int(e.data_match.group(1))
50
+ if CURRENT == 5:
51
+ return await e.edit(
52
+ STRINGS[5],
53
+ buttons=Button.inline("<< Back", "initbk_4"),
54
+ link_preview=False,
55
+ )
56
+
57
+ await e.edit(
58
+ STRINGS[CURRENT],
59
+ buttons=[
60
+ Button.inline("<<", f"initbk_{str(CURRENT - 1)}"),
61
+ Button.inline(">>", f"initft_{str(CURRENT + 1)}"),
62
+ ],
63
+ link_preview=False,
64
+ )
65
+
66
+
67
+ @callback(re.compile("initbk_(\\d+)"))
68
+ async def ineiq(e):
69
+ CURRENT = int(e.data_match.group(1))
70
+ if CURRENT == 1:
71
+ return await e.edit(
72
+ STRINGS[1],
73
+ buttons=Button.inline("Start Back >>", "initft_2"),
74
+ link_preview=False,
75
+ )
76
+
77
+ await e.edit(
78
+ STRINGS[CURRENT],
79
+ buttons=[
80
+ Button.inline("<<", f"initbk_{str(CURRENT - 1)}"),
81
+ Button.inline(">>", f"initft_{str(CURRENT + 1)}"),
82
+ ],
83
+ link_preview=False,
84
+ )
assistant/inlinestuff.py ADDED
@@ -0,0 +1,623 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 base64
9
+ import inspect
10
+ from datetime import datetime
11
+ from html import unescape
12
+ from random import choice
13
+ from re import compile as re_compile
14
+
15
+ from bs4 import BeautifulSoup as bs
16
+ from telethon import Button
17
+ from telethon.tl.alltlobjects import LAYER, tlobjects
18
+ from telethon.tl.types import DocumentAttributeAudio as Audio
19
+ from telethon.tl.types import InputWebDocument as wb
20
+
21
+ from pyUltroid.fns.misc import google_search
22
+ from pyUltroid.fns.tools import (
23
+ _webupload_cache,
24
+ async_searcher,
25
+ get_ofox,
26
+ saavn_search,
27
+ webuploader,
28
+ )
29
+
30
+ from . import *
31
+ from . import _ult_cache
32
+
33
+ SUP_BUTTONS = [
34
+ [
35
+ Button.url("• Repo •", url="https://github.com/TeamUltroid/Ultroid"),
36
+ Button.url("• Support •", url="t.me/UltroidSupportChat"),
37
+ ],
38
+ ]
39
+
40
+ ofox = "https://graph.org/file/231f0049fcd722824f13b.jpg"
41
+ gugirl = "https://graph.org/file/0df54ae4541abca96aa11.jpg"
42
+ ultpic = "https://graph.org/file/4136aa1650bc9d4109cc5.jpg"
43
+
44
+ apis = [
45
+ "QUl6YVN5QXlEQnNZM1dSdEI1WVBDNmFCX3c4SkF5NlpkWE5jNkZV",
46
+ "QUl6YVN5QkYwenhMbFlsUE1wOXh3TVFxVktDUVJxOERnZHJMWHNn",
47
+ "QUl6YVN5RGRPS253blB3VklRX2xiSDVzWUU0Rm9YakFLSVFWMERR",
48
+ ]
49
+
50
+
51
+ @in_pattern("ofox", owner=True)
52
+ async def _(e):
53
+ try:
54
+ match = e.text.split(" ", maxsplit=1)[1]
55
+ except IndexError:
56
+ kkkk = e.builder.article(
57
+ title="Enter Device Codename",
58
+ thumb=wb(ofox, 0, "image/jpeg", []),
59
+ text="**OFᴏx🦊Rᴇᴄᴏᴠᴇʀʏ**\n\nYou didn't search anything",
60
+ buttons=Button.switch_inline("Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="ofox ", same_peer=True),
61
+ )
62
+ return await e.answer([kkkk])
63
+ device, releases = await get_ofox(match)
64
+ if device.get("detail") is None:
65
+ fox = []
66
+ fullname = device["full_name"]
67
+ codename = device["codename"]
68
+ str(device["supported"])
69
+ maintainer = device["maintainer"]["name"]
70
+ link = f"https://orangefox.download/device/{codename}"
71
+ for data in releases["data"]:
72
+ release = data["type"]
73
+ version = data["version"]
74
+ size = humanbytes(data["size"])
75
+ release_date = datetime.utcfromtimestamp(data["date"]).strftime("%Y-%m-%d")
76
+ text = f"[\xad]({ofox})**OʀᴀɴɢᴇFᴏx Rᴇᴄᴏᴠᴇʀʏ Fᴏʀ**\n\n"
77
+ text += f"` Fᴜʟʟ Nᴀᴍᴇ: {fullname}`\n"
78
+ text += f"` Cᴏᴅᴇɴᴀᴍᴇ: {codename}`\n"
79
+ text += f"` Mᴀɪɴᴛᴀɪɴᴇʀ: {maintainer}`\n"
80
+ text += f"` Bᴜɪʟᴅ Tʏᴘᴇ: {release}`\n"
81
+ text += f"` Vᴇʀsɪᴏɴ: {version}`\n"
82
+ text += f"` Sɪᴢᴇ: {size}`\n"
83
+ text += f"` Bᴜɪʟᴅ Dᴀᴛᴇ: {release_date}`"
84
+ fox.append(
85
+ await e.builder.article(
86
+ title=f"{fullname}",
87
+ description=f"{version}\n{release_date}",
88
+ text=text,
89
+ thumb=wb(ofox, 0, "image/jpeg", []),
90
+ link_preview=True,
91
+ buttons=[
92
+ Button.url("Dᴏᴡɴʟᴏᴀᴅ", url=f"{link}"),
93
+ Button.switch_inline(
94
+ "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="ofox ", same_peer=True
95
+ ),
96
+ ],
97
+ )
98
+ )
99
+ await e.answer(
100
+ fox, switch_pm="OrangeFox Recovery Search.", switch_pm_param="start"
101
+ )
102
+ else:
103
+ await e.answer(
104
+ [], switch_pm="OrangeFox Recovery Search.", switch_pm_param="start"
105
+ )
106
+
107
+
108
+ @in_pattern("fl2lnk ?(.*)", owner=True)
109
+ async def _(e):
110
+ match = e.pattern_match.group(1)
111
+ chat_id, msg_id = match.split(":")
112
+ filename = _webupload_cache[int(chat_id)][int(msg_id)]
113
+ if "/" in filename:
114
+ filename = filename.split("/")[-1]
115
+ __cache = f"{chat_id}:{msg_id}"
116
+ buttons = [
117
+ [
118
+ Button.inline("anonfiles", data=f"flanonfiles//{__cache}"),
119
+ Button.inline("transfer", data=f"fltransfer//{__cache}"),
120
+ ],
121
+ [
122
+ Button.inline("bayfiles", data=f"flbayfiles//{__cache}"),
123
+ Button.inline("x0.at", data=f"flx0.at//{__cache}"),
124
+ ],
125
+ [
126
+ Button.inline("file.io", data=f"flfile.io//{__cache}"),
127
+ Button.inline("siasky", data=f"flsiasky//{__cache}"),
128
+ ],
129
+ ]
130
+ try:
131
+ lnk = [
132
+ await e.builder.article(
133
+ title=f"Upload {filename}",
134
+ text=f"**File:**\n{filename}",
135
+ buttons=buttons,
136
+ )
137
+ ]
138
+ except BaseException as er:
139
+ LOGS.exception(er)
140
+ lnk = [
141
+ await e.builder.article(
142
+ title="fl2lnk",
143
+ text="File not found",
144
+ )
145
+ ]
146
+ await e.answer(lnk, switch_pm="File to Link.", switch_pm_param="start")
147
+
148
+
149
+ @callback(
150
+ re_compile(
151
+ "fl(.*)",
152
+ ),
153
+ owner=True,
154
+ )
155
+ async def _(e):
156
+ t = (e.data).decode("UTF-8")
157
+ data = t[2:]
158
+ host = data.split("//")[0]
159
+ chat_id, msg_id = data.split("//")[1].split(":")
160
+ filename = _webupload_cache[int(chat_id)][int(msg_id)]
161
+ if "/" in filename:
162
+ filename = filename.split("/")[-1]
163
+ await e.edit(f"Uploading `{filename}` on {host}")
164
+ link = (await webuploader(chat_id, msg_id, host)).strip().replace("\n", "")
165
+ await e.edit(f"Uploaded `{filename}` on {host}.", buttons=Button.url("View", link))
166
+
167
+
168
+ @in_pattern("repo", owner=True)
169
+ async def repo(e):
170
+ res = [
171
+ await e.builder.article(
172
+ title="Ultroid Userbot",
173
+ description="Userbot | Telethon",
174
+ thumb=wb(ultpic, 0, "image/jpeg", []),
175
+ text="• **ULTROID USERBOT** •",
176
+ buttons=SUP_BUTTONS,
177
+ ),
178
+ ]
179
+ await e.answer(res, switch_pm="Ultroid Repo.", switch_pm_param="start")
180
+
181
+
182
+ @in_pattern("go", owner=True)
183
+ async def gsearch(q_event):
184
+ try:
185
+ match = q_event.text.split(maxsplit=1)[1]
186
+ except IndexError:
187
+ return await q_event.answer(
188
+ [], switch_pm="Google Search. Enter a query!", switch_pm_param="start"
189
+ )
190
+ searcher = []
191
+ gresults = await google_search(match)
192
+ for i in gresults:
193
+ try:
194
+ title = i["title"]
195
+ link = i["link"]
196
+ desc = i["description"]
197
+ searcher.append(
198
+ await q_event.builder.article(
199
+ title=title,
200
+ description=desc,
201
+ thumb=wb(gugirl, 0, "image/jpeg", []),
202
+ text=f"**Gᴏᴏɢʟᴇ Sᴇᴀʀᴄʜ**\n\n**••Tɪᴛʟᴇ••**\n`{title}`\n\n**••Dᴇsᴄʀɪᴘᴛɪᴏɴ••**\n`{desc}`",
203
+ link_preview=False,
204
+ buttons=[
205
+ [Button.url("Lɪɴᴋ", url=f"{link}")],
206
+ [
207
+ Button.switch_inline(
208
+ "Sᴇᴀʀᴄʜ Aɢᴀɪɴ",
209
+ query="go ",
210
+ same_peer=True,
211
+ ),
212
+ Button.switch_inline(
213
+ "Sʜᴀʀᴇ",
214
+ query=f"go {match}",
215
+ same_peer=False,
216
+ ),
217
+ ],
218
+ ],
219
+ ),
220
+ )
221
+ except IndexError:
222
+ break
223
+ await q_event.answer(searcher, switch_pm="Google Search.", switch_pm_param="start")
224
+
225
+
226
+ @in_pattern("mods", owner=True)
227
+ async def _(e):
228
+ try:
229
+ quer = e.text.split(" ", maxsplit=1)[1]
230
+ except IndexError:
231
+ return await e.answer(
232
+ [], switch_pm="Mod Apps Search. Enter app name!", switch_pm_param="start"
233
+ )
234
+ start = 0 * 3 + 1
235
+ da = base64.b64decode(choice(apis)).decode("ascii")
236
+ url = f"https://www.googleapis.com/customsearch/v1?key={da}&cx=25b3b50edb928435b&q={quer}&start={start}"
237
+ data = await async_searcher(url, re_json=True)
238
+ search_items = data.get("items", [])
239
+ modss = []
240
+ for a in search_items:
241
+ title = a.get("title")
242
+ desc = a.get("snippet")
243
+ link = a.get("link")
244
+ text = f"**••Tɪᴛʟᴇ••** `{title}`\n\n"
245
+ text += f"**Dᴇsᴄʀɪᴘᴛɪᴏɴ** `{desc}`"
246
+ modss.append(
247
+ await e.builder.article(
248
+ title=title,
249
+ description=desc,
250
+ text=text,
251
+ link_preview=True,
252
+ buttons=[
253
+ [Button.url("Dᴏᴡɴʟᴏᴀᴅ", url=f"{link}")],
254
+ [
255
+ Button.switch_inline(
256
+ "Mᴏʀᴇ Mᴏᴅs",
257
+ query="mods ",
258
+ same_peer=True,
259
+ ),
260
+ Button.switch_inline(
261
+ "Sʜᴀʀᴇ",
262
+ query=f"mods {quer}",
263
+ same_peer=False,
264
+ ),
265
+ ],
266
+ ],
267
+ ),
268
+ )
269
+ await e.answer(modss, switch_pm="Search Mod Applications.", switch_pm_param="start")
270
+
271
+
272
+ APP_CACHE = {}
273
+ RECENTS = {}
274
+ PLAY_API = "https://googleplay.onrender.com/api/apps?q="
275
+
276
+
277
+ @in_pattern("app", owner=True)
278
+ async def _(e):
279
+ try:
280
+ f = e.text.split(maxsplit=1)[1].lower()
281
+ except IndexError:
282
+ get_string("instu_1")
283
+ res = []
284
+ if APP_CACHE and RECENTS.get(e.sender_id):
285
+ res.extend(
286
+ APP_CACHE[a][0] for a in RECENTS[e.sender_id] if APP_CACHE.get(a)
287
+ )
288
+ return await e.answer(
289
+ res, switch_pm=get_string("instu_2"), switch_pm_param="start"
290
+ )
291
+ try:
292
+ return await e.answer(
293
+ APP_CACHE[f], switch_pm="Application Searcher.", switch_pm_param="start"
294
+ )
295
+ except KeyError:
296
+ pass
297
+ foles = []
298
+ url = PLAY_API + f.replace(" ", "+")
299
+ aap = await async_searcher(url, re_json=True)
300
+ for z in aap["results"][:50]:
301
+ url = "https://play.google.com/store/apps/details?id=" + z["appId"]
302
+ name = z["title"]
303
+ desc = unescape(z["summary"])[:300].replace("<br>", "\n") + "..."
304
+ dev = z["developer"]["devId"]
305
+ text = f"**••Aᴘᴘ Nᴀᴍᴇ••** [{name}]({url})\n"
306
+ text += f"**••Dᴇᴠᴇʟᴏᴘᴇʀ••** `{dev}`\n"
307
+ text += f"**••Dᴇsᴄʀɪᴘᴛɪᴏɴ••**\n`{desc}`"
308
+ foles.append(
309
+ await e.builder.article(
310
+ title=name,
311
+ description=dev,
312
+ thumb=wb(z["icon"], 0, "image/jpeg", []),
313
+ text=text,
314
+ link_preview=True,
315
+ buttons=[
316
+ [Button.url("Lɪɴᴋ", url=url)],
317
+ [
318
+ Button.switch_inline(
319
+ "Mᴏʀᴇ Aᴘᴘs",
320
+ query="app ",
321
+ same_peer=True,
322
+ ),
323
+ Button.switch_inline(
324
+ "Sʜᴀʀᴇ",
325
+ query=f"app {f}",
326
+ same_peer=False,
327
+ ),
328
+ ],
329
+ ],
330
+ ),
331
+ )
332
+ APP_CACHE.update({f: foles})
333
+ if RECENTS.get(e.sender_id):
334
+ RECENTS[e.sender_id].append(f)
335
+ else:
336
+ RECENTS.update({e.sender_id: [f]})
337
+ await e.answer(foles, switch_pm="Application Searcher.", switch_pm_param="start")
338
+
339
+
340
+ PISTON_URI = "https://emkc.org/api/v2/piston/"
341
+ PISTON_LANGS = {}
342
+
343
+
344
+ @in_pattern("run", owner=True)
345
+ async def piston_run(event):
346
+ try:
347
+ lang = event.text.split()[1]
348
+ code = event.text.split(maxsplit=2)[2]
349
+ except IndexError:
350
+ result = await event.builder.article(
351
+ title="Bad Query",
352
+ description="Usage: [Language] [code]",
353
+ thumb=wb(
354
+ "https://graph.org/file/e33c57fc5f1044547e4d8.jpg", 0, "image/jpeg", []
355
+ ),
356
+ text=f'**Inline Usage**\n\n`@{asst.me.username} run python print("hello world")`\n\n[Language List](https://graph.org/Ultroid-09-01-6)',
357
+ )
358
+ return await event.answer([result])
359
+ if not PISTON_LANGS:
360
+ se = await async_searcher(f"{PISTON_URI}runtimes", re_json=True)
361
+ PISTON_LANGS.update({lang.pop("language"): lang for lang in se})
362
+ if lang in PISTON_LANGS.keys():
363
+ version = PISTON_LANGS[lang]["version"]
364
+ else:
365
+ result = await event.builder.article(
366
+ title="Unsupported Language",
367
+ description="Usage: [Language] [code]",
368
+ thumb=wb(
369
+ "https://graph.org/file/e33c57fc5f1044547e4d8.jpg", 0, "image/jpeg", []
370
+ ),
371
+ text=f'**Inline Usage**\n\n`@{asst.me.username} run python print("hello world")`\n\n[Language List](https://graph.org/Ultroid-09-01-6)',
372
+ )
373
+ return await event.answer([result])
374
+ output = await async_searcher(
375
+ f"{PISTON_URI}execute",
376
+ post=True,
377
+ json={
378
+ "language": lang,
379
+ "version": version,
380
+ "files": [{"content": code}],
381
+ },
382
+ re_json=True,
383
+ )
384
+
385
+ output = output["run"]["output"] or get_string("instu_4")
386
+ if len(output) > 3000:
387
+ output = f"{output[:3000]}..."
388
+ result = await event.builder.article(
389
+ title="Result",
390
+ description=output,
391
+ text=f"• **Language:**\n`{lang}`\n\n• **Code:**\n`{code}`\n\n• **Result:**\n`{output}`",
392
+ thumb=wb(
393
+ "https://graph.org/file/871ee4a481f58117dccc4.jpg", 0, "image/jpeg", []
394
+ ),
395
+ buttons=Button.switch_inline("Fork", query=event.text, same_peer=True),
396
+ )
397
+ await event.answer([result], switch_pm="• Piston •", switch_pm_param="start")
398
+
399
+
400
+ FDROID_ = {}
401
+
402
+
403
+ @in_pattern("fdroid", owner=True)
404
+ async def do_magic(event):
405
+ try:
406
+ match = event.text.split(" ", maxsplit=1)[1].lower()
407
+ except IndexError:
408
+ return await event.answer(
409
+ [], switch_pm="Enter Query to Search", switch_pm_param="start"
410
+ )
411
+ if FDROID_.get(match):
412
+ return await event.answer(
413
+ FDROID_[match], switch_pm=f"• Results for {match}", switch_pm_param="start"
414
+ )
415
+ link = "https://search.f-droid.org/?q=" + match.replace(" ", "+")
416
+ content = await async_searcher(link, re_content=True)
417
+ BSC = bs(content, "html.parser", from_encoding="utf-8")
418
+ ress = []
419
+ for dat in BSC.find_all("a", "package-header")[:10]:
420
+ image = dat.find("img", "package-icon")["src"]
421
+ if image.endswith("/"):
422
+ image = "https://graph.org/file/a8dd4a92c5a53a89d0eff.jpg"
423
+ title = dat.find("h4", "package-name").text.strip()
424
+ desc = dat.find("span", "package-summary").text.strip()
425
+ text = f"• **Name :** `{title}`\n\n"
426
+ text += f"• **Description :** `{desc}`\n"
427
+ text += f"• **License :** `{dat.find('span', 'package-license').text.strip()}`"
428
+ imga = wb(image, 0, "image/jpeg", [])
429
+ ress.append(
430
+ await event.builder.article(
431
+ title=title,
432
+ type="photo",
433
+ description=desc,
434
+ text=text,
435
+ content=imga,
436
+ thumb=imga,
437
+ include_media=True,
438
+ buttons=[
439
+ Button.inline(
440
+ "• Download •", "fd" + dat["href"].split("packages/")[-1]
441
+ ),
442
+ Button.switch_inline("• Share •", query=event.text),
443
+ ],
444
+ )
445
+ )
446
+ msg = f"Showing {len(ress)} Results!" if ress else "No Results Found"
447
+ FDROID_.update({match: ress})
448
+ await event.answer(ress, switch_pm=msg, switch_pm_param="start")
449
+
450
+
451
+ # Thanks to OpenSource
452
+ _bearer_collected = [
453
+ "AAAAAAAAAAAAAAAAAAAAALIKKgEAAAAA1DRuS%2BI7ZRKiagD6KHYmreaXomo%3DP5Vaje4UTtEkODg0fX7nCh5laSrchhtLxeyEqxXpv0w9ZKspLD",
454
+ "AAAAAAAAAAAAAAAAAAAAAL5iUAEAAAAAmo6FYRjqdKlI3cNziIm%2BHUQB9Xs%3DS31pj0mxARMTOk2g9dvQ1yP9wknvY4FPBPUlE00smJcncw4dPR",
455
+ "AAAAAAAAAAAAAAAAAAAAAN6sVgEAAAAAMMjMMWrwgGyv7YQOWN%2FSAsO5SGM%3Dg8MG9Jq93Rlllaok6eht7HvRCruN4Vpzp4NaVsZaaHHWSTzKI8",
456
+ ]
457
+
458
+
459
+ @in_pattern("twitter", owner=True)
460
+ async def twitter_search(event):
461
+ try:
462
+ match = event.text.split(maxsplit=1)[1].lower()
463
+ except IndexError:
464
+ return await event.answer(
465
+ [], switch_pm="Enter Query to Search", switch_pm_param="start"
466
+ )
467
+ try:
468
+ return await event.answer(
469
+ _ult_cache["twitter"][match],
470
+ switch_pm="• Twitter Search •",
471
+ switch_pm_param="start",
472
+ )
473
+ except KeyError:
474
+ pass
475
+ headers = {"Authorization": f"bearer {choice(_bearer_collected)}"}
476
+ res = await async_searcher(
477
+ f"https://api.twitter.com/1.1/users/search.json?q={match}",
478
+ headers=headers,
479
+ re_json=True,
480
+ )
481
+ reso = []
482
+ for user in res:
483
+ thumb = wb(user["profile_image_url_https"], 0, "image/jpeg", [])
484
+ if user.get("profile_banner_url"):
485
+ url = user["profile_banner_url"]
486
+ text = f"[\xad]({url})• **Name :** `{user['name']}`\n"
487
+ else:
488
+ text = f"• **Name :** `{user['name']}`\n"
489
+ text += f"• **Description :** `{user['description']}`\n"
490
+ text += f"• **Username :** `@{user['screen_name']}`\n"
491
+ text += f"• **Followers :** `{user['followers_count']}` • **Following :** `{user['friends_count']}`\n"
492
+ pro_ = "https://twitter.com/" + user["screen_name"]
493
+ text += f"• **Link :** [Click Here]({pro_})\n_"
494
+ reso.append(
495
+ await event.builder.article(
496
+ title=user["name"],
497
+ description=user["description"],
498
+ url=pro_,
499
+ text=text,
500
+ thumb=thumb,
501
+ )
502
+ )
503
+ swi_ = f"🐦 Showing {len(reso)} Results!" if reso else "No User Found :("
504
+ await event.answer(reso, switch_pm=swi_, switch_pm_param="start")
505
+ if _ult_cache.get("twitter"):
506
+ _ult_cache["twitter"].update({match: reso})
507
+ else:
508
+ _ult_cache.update({"twitter": {match: reso}})
509
+
510
+
511
+ _savn_cache = {}
512
+
513
+
514
+ @in_pattern("saavn", owner=True)
515
+ async def savn_s(event):
516
+ try:
517
+ query = event.text.split(maxsplit=1)[1].lower()
518
+ except IndexError:
519
+ return await event.answer(
520
+ [], switch_pm="Enter Query to search 🔍", switch_pm_param="start"
521
+ )
522
+ if query in _savn_cache:
523
+ return await event.answer(
524
+ _savn_cache[query],
525
+ switch_pm=f"Showing Results for {query}",
526
+ switch_pm_param="start",
527
+ )
528
+ results = await saavn_search(query)
529
+ swi = "🎵 Saavn Search" if results else "No Results Found!"
530
+ res = []
531
+ for song in results:
532
+ thumb = wb(song["image"], 0, "image/jpeg", [])
533
+ text = f"• **Title :** {song['title']}"
534
+ text += f"\n• **Year :** {song['year']}"
535
+ text += f"\n• **Lang :** {song['language']}"
536
+ text += f"\n• **Artist :** {song['artists']}"
537
+ text += f"\n• **Release Date :** {song['release_date']}"
538
+ res.append(
539
+ await event.builder.article(
540
+ title=song["title"],
541
+ description=song["artists"],
542
+ type="audio",
543
+ text=text,
544
+ include_media=True,
545
+ buttons=Button.switch_inline(
546
+ "Search Again 🔍", query="saavn", same_peer=True
547
+ ),
548
+ thumb=thumb,
549
+ content=wb(
550
+ song["url"],
551
+ 0,
552
+ "audio/mp4",
553
+ [
554
+ Audio(
555
+ title=song["title"],
556
+ duration=int(song["duration"]),
557
+ performer=song["artists"],
558
+ )
559
+ ],
560
+ ),
561
+ )
562
+ )
563
+ await event.answer(res, switch_pm=swi, switch_pm_param="start")
564
+ _savn_cache.update({query: res})
565
+
566
+
567
+ @in_pattern("tl", owner=True)
568
+ async def inline_tl(ult):
569
+ try:
570
+ match = ult.text.split(maxsplit=1)[1]
571
+ except IndexError:
572
+ text = f"**Telegram TlObjects Searcher.**\n__(Don't use if you don't know what it is!)__\n\n• Example Usage\n`@{asst.me.username} tl GetFullUserRequest`"
573
+ return await ult.answer(
574
+ [
575
+ await ult.builder.article(
576
+ title="How to Use?",
577
+ description="Tl Searcher by Ultroid",
578
+ url="https://t.me/TeamUltroid",
579
+ text=text,
580
+ )
581
+ ],
582
+ switch_pm="Tl Search 🔍",
583
+ switch_pm_param="start",
584
+ )
585
+ res = []
586
+ for key in tlobjects.values():
587
+ if match.lower() in key.__name__.lower():
588
+ tyyp = "Function" if "tl.functions." in str(key) else "Type"
589
+ text = f"**Name:** `{key.__name__}`\n"
590
+ text += f"**Category:** `{tyyp}`\n"
591
+ text += f"\n`from {key.__module__} import {key.__name__}`\n\n"
592
+ if args := str(inspect.signature(key))[1:][:-1]:
593
+ text += "**Parameter:**\n"
594
+ for para in args.split(","):
595
+ text += " " * 4 + "`" + para + "`\n"
596
+ text += f"\n**Layer:** `{LAYER}`"
597
+ res.append(
598
+ await ult.builder.article(
599
+ title=key.__name__,
600
+ description=tyyp,
601
+ url="https://t.me/TeamUltroid",
602
+ text=text[:4000],
603
+ )
604
+ )
605
+ mo = f"Showing {len(res)} results!" if res else f"No Results for {match}!"
606
+ await ult.answer(res[:50], switch_pm=mo, switch_pm_param="start")
607
+
608
+
609
+ InlinePlugin.update(
610
+ {
611
+ "Pʟᴀʏ Sᴛᴏʀᴇ Aᴘᴘs": "app telegram",
612
+ "Mᴏᴅᴅᴇᴅ Aᴘᴘs": "mods minecraft",
613
+ "Sᴇᴀʀᴄʜ Oɴ Gᴏᴏɢʟᴇ": "go TeamUltroid",
614
+ "WʜɪSᴘᴇʀ": "wspr @username Hello🎉",
615
+ "YᴏᴜTᴜʙᴇ Dᴏᴡɴʟᴏᴀᴅᴇʀ": "yt Ed Sheeran Perfect",
616
+ "Piston Eval": "run javascript console.log('Hello Ultroid')",
617
+ "OʀᴀɴɢᴇFᴏx🦊": "ofox beryllium",
618
+ "Tᴡɪᴛᴛᴇʀ Usᴇʀ": "twitter theultroid",
619
+ "Fᴅʀᴏɪᴅ Sᴇᴀʀᴄʜ": "fdroid telegram",
620
+ "Sᴀᴀᴠɴ sᴇᴀʀᴄʜ": "saavn",
621
+ "Tʟ Sᴇᴀʀᴄʜ": "tl",
622
+ }
623
+ )
assistant/localization.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 . import (
11
+ Button,
12
+ ULTConfig,
13
+ callback,
14
+ get_back_button,
15
+ get_languages,
16
+ get_string,
17
+ udB,
18
+ )
19
+
20
+
21
+ @callback("lang", owner=True)
22
+ async def setlang(event):
23
+ languages = get_languages()
24
+ tultd = [
25
+ Button.inline(
26
+ f"{languages[ult]['natively']} [{ult.lower()}]",
27
+ data=f"set_{ult}",
28
+ )
29
+ for ult in languages
30
+ ]
31
+ buttons = list(zip(tultd[::2], tultd[1::2]))
32
+ if len(tultd) % 2 == 1:
33
+ buttons.append((tultd[-1],))
34
+ buttons.append([Button.inline("« Back", data="mainmenu")])
35
+ await event.edit(get_string("ast_4"), buttons=buttons)
36
+
37
+
38
+ @callback(re.compile(b"set_(.*)"), owner=True)
39
+ async def settt(event):
40
+ lang = event.data_match.group(1).decode("UTF-8")
41
+ languages = get_languages()
42
+ ULTConfig.lang = lang
43
+ udB.del_key("language") if lang == "en" else udB.set_key("language", lang)
44
+ await event.edit(
45
+ f"Your language has been set to {languages[lang]['natively']} [{lang}].",
46
+ buttons=get_back_button("lang"),
47
+ )
assistant/manager/__init__.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
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 pyUltroid._misc._decorators import ultroid_cmd
9
+ from pyUltroid.fns.helper import inline_mention
10
+
11
+ from .. import *
assistant/manager/_help.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 *
9
+
10
+ START = """
11
+ 🪅 **Help Menu** 🪅
12
+
13
+ ✘ /start : Check I am Alive or not.
14
+ ✘ /help : Get This Message.
15
+ ✘ /repo : Get Bot's Repo..
16
+
17
+ 🧑‍💻 Join **@TeamUltroid**
18
+ """
19
+
20
+ ADMINTOOLS = """✘ **AdminTools** ✘
21
+
22
+ • /pin : Pins the Replied Message
23
+ • /pinned : Get Pinned message in chat.
24
+ • /unpin : Unpin the Replied message
25
+ • /unpin all : Unpin all Pinned Messages.
26
+
27
+ • /ban (username/id/reply) : Ban the User
28
+ • /unban (username/id/reply) : UnBan the User.
29
+
30
+ • /mute (username/id/reply) : Mute the User.
31
+ • /unmute (username/id/reply) : Unmute the User.
32
+
33
+ • /tban (username/id/reply) (time) : Temporary ban a user
34
+ • /tmute (username/id/reply) (time) : temporary Mutes a User.
35
+
36
+ • /purge (purge messages)
37
+
38
+ • /setgpic (reply photo) : keep Chat Photo of Group.
39
+ • /delgpic : remove current chat Photo."""
40
+
41
+ UTILITIES = """
42
+ ✘ ** Utilities ** ✘
43
+
44
+ • /info (reply/username/id) : get detailed info of user.
45
+ • /id : get chat/user id.
46
+ • /tr : Translate Languages..
47
+ • /q : Create Quotes.
48
+
49
+ • /paste (reply file/text) : paste content on Spaceb.in
50
+ • /meaning (text) : Get Meaning of that Word.
51
+ • /google (query) : Search Something on Google..
52
+
53
+ • /suggest (query/reply) : Creates a Yes / No Poll.
54
+ """
55
+
56
+ LOCKS = """
57
+ ✘ ** Locks ** ✘
58
+
59
+ • /lock (query) : lock particular content in chat.
60
+ • /unlock (query) : Unlock some content.
61
+
62
+ • All Queries
63
+ - `msgs` : for messages.
64
+ - `inlines` : for inline queries.
65
+ - `media` : for all medias.
66
+ - `games` : for games.
67
+ - `sticker` : for stickers.
68
+ - `polls` : for polls.
69
+ - `gif` : for gifs.
70
+ - `pin` : for pins.
71
+ - `changeinfo` : for change info right.
72
+ """
73
+
74
+ MISC = """
75
+ ✘ **Misc** ✘
76
+
77
+ • /joke : Get Random Jokes.
78
+ • /decide : Decide Something..
79
+
80
+ **✘ Stickertools ✘**
81
+ • /kang : add sticker to your pack.
82
+ • /listpack : get all of yours pack..
83
+ """
84
+
85
+ STRINGS = {"Admintools": ADMINTOOLS, "locks": LOCKS, "Utils": UTILITIES, "Misc": MISC}
86
+
87
+ MNGE = udB.get_key("MNGR_EMOJI") or "•"
88
+
89
+
90
+ def get_buttons():
91
+ BTTS = []
92
+ keys = STRINGS.copy()
93
+ while keys:
94
+ BT = []
95
+ for i in list(keys)[:2]:
96
+ text = f"{MNGE} {i} {MNGE}"
97
+ BT.append(Button.inline(text, f"hlp_{i}"))
98
+ del keys[i]
99
+ BTTS.append(BT)
100
+ url = f"https://t.me/{asst.me.username}?startgroup=true"
101
+ BTTS.append([Button.url("Add me to Group", url)])
102
+ return BTTS
103
+
104
+
105
+ @asst_cmd(pattern="help")
106
+ async def helpish(event):
107
+ if not event.is_private:
108
+ url = f"https://t.me/{asst.me.username}?start=start"
109
+ return await event.reply(
110
+ "Contact me in PM for help!", buttons=Button.url("Click me for Help", url)
111
+ )
112
+ if str(event.sender_id) in owner_and_sudos() and (
113
+ udB.get_key("DUAL_MODE") and (udB.get_key("DUAL_HNDLR") == "/")
114
+ ):
115
+ return
116
+ await event.reply(START, buttons=get_buttons())
117
+
118
+
119
+ @callback("mngbtn", owner=True)
120
+ async def ehwhshd(e):
121
+ buttons = get_buttons()
122
+ buttons.append([Button.inline("<< Back", "open")])
123
+ await e.edit(buttons=buttons)
124
+
125
+
126
+ @callback("mnghome")
127
+ async def home_aja(e):
128
+ await e.edit(START, buttons=get_buttons())
129
+
130
+
131
+ @callback(re.compile("hlp_(.*)"))
132
+ async def do_something(event):
133
+ match = event.pattern_match.group(1).strip().decode("utf-8")
134
+ await event.edit(STRINGS[match], buttons=Button.inline("<< Back", "mnghome"))
assistant/manager/_on_adds.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 import events
9
+
10
+ from . import *
11
+
12
+
13
+ @asst.on(events.ChatAction(func=lambda x: x.user_added))
14
+ async def dueha(e):
15
+ user = await e.get_user()
16
+ if not user.is_self:
17
+ return
18
+ sm = udB.get_key("ON_MNGR_ADD")
19
+ if sm == "OFF":
20
+ return
21
+ if not sm:
22
+ sm = "Thanks for Adding me :)"
23
+ await e.reply(sm, link_preview=False)
assistant/manager/admins.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.errors.rpcerrorlist import UserNotParticipantError
11
+
12
+ from pyUltroid import _ult_cache
13
+
14
+ from . import *
15
+
16
+
17
+ @ultroid_cmd(pattern="d(kick|ban)", manager=True, require="ban_users")
18
+ async def dowj(e):
19
+ replied = await e.get_reply_message()
20
+ if replied:
21
+ user = replied.sender_id
22
+ else:
23
+ return await e.eor("Reply to a message...")
24
+ try:
25
+ await replied.delete()
26
+ if e.pattern_match.group(1).strip() == "kick":
27
+ await e.client.kick_participant(e.chat_id, user)
28
+ te = "Kicked"
29
+ else:
30
+ await e.client.edit_permissions(e.chat_id, user, view_messages=False)
31
+ te = "Banned"
32
+ await e.eor(f"{te} Successfully!")
33
+ except Exception as E:
34
+ await e.eor(str(E))
35
+
36
+
37
+ @callback(re.compile("cc_(.*)"), func=_ult_cache.get("admin_callback"))
38
+ async def callback_(event):
39
+ data = event.data_match.group(1).decode("utf-8")
40
+ if data not in _ult_cache.get("admin_callback", {}):
41
+ return
42
+ try:
43
+ perm = await event.client.get_permissions(event.chat_id, event.sender_id)
44
+ except UserNotParticipantError:
45
+ return await event.answer("Join the Group First!", alert=True)
46
+ if not perm.is_admin:
47
+ return await event.answer("You are not an Admin!", alert=True)
48
+ _ult_cache["admin_callback"].update({data: (event.sender, perm)})
49
+ await event.answer("Verification Done!")
50
+ await event.delete()
assistant/manager/afk.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
+ from datetime import datetime as dt
9
+
10
+ from telethon.events import NewMessage
11
+ from telethon.tl.types import (
12
+ Message,
13
+ MessageEntityMention,
14
+ MessageEntityMentionName,
15
+ User,
16
+ )
17
+ from telethon.utils import get_display_name
18
+
19
+ from pyUltroid.fns.helper import inline_mention, time_formatter
20
+
21
+ from . import asst, asst_cmd
22
+
23
+ AFK = {}
24
+
25
+
26
+ @asst_cmd(pattern="afk", func=lambda x: not x.is_private)
27
+ async def go_afk(event):
28
+ sender = await event.get_sender()
29
+ if (not isinstance(sender, User)) or sender.bot:
30
+ return
31
+ try:
32
+ reason = event.text.split(" ", maxsplit=1)[1]
33
+ except IndexError:
34
+ reason = None
35
+ if event.is_reply and not reason:
36
+ replied = await event.get_reply_message()
37
+ if not reason and replied.text and not replied.media:
38
+ reason = replied.text
39
+ else:
40
+ reason = replied
41
+ time_ = dt.now()
42
+ if AFK.get(event.chat_id):
43
+ AFK[event.chat_id].update({event.sender_id: {"reason": reason, "time": time_}})
44
+ else:
45
+ AFK.update(
46
+ {event.chat_id: {event.sender_id: {"reason": reason, "time": time_}}}
47
+ )
48
+ mention = inline_mention(sender)
49
+ msg = f"**{mention} went AFK Now!**"
50
+ if reason and not isinstance(reason, str):
51
+ await event.reply(reason)
52
+ else:
53
+ msg += f"\n\n**Reason : ** `{reason}`"
54
+ await event.reply(msg)
55
+
56
+
57
+ @asst.on(NewMessage(func=lambda x: AFK.get(x.chat_id) and not x.is_private))
58
+ async def make_change(event):
59
+ if event.text.startswith("/afk"):
60
+ return
61
+ sender = await event.get_sender()
62
+ if (not isinstance(sender, User)) or sender.bot:
63
+ return
64
+ chat_ = AFK[event.chat_id]
65
+ if event.sender_id in chat_.keys():
66
+ name = get_display_name(event.sender)
67
+ cha_send = chat_[event.sender_id]
68
+ time_ = time_formatter((dt.now() - cha_send["time"]).seconds * 1000)
69
+ msg = f"**{name}** is No Longer AFK!\n**Was AFK for** {time_}"
70
+ await event.reply(msg)
71
+ del chat_[event.sender_id]
72
+ if not chat_:
73
+ del AFK[event.chat_id]
74
+ ST_SPAM = []
75
+ replied = await event.get_reply_message()
76
+ if replied:
77
+ name = get_display_name(replied.sender)
78
+ if replied.sender_id in chat_.keys():
79
+ s_der = chat_[replied.sender_id]
80
+ res_ = s_der["reason"]
81
+ time_ = time_formatter((dt.now() - s_der["time"]).seconds * 1000)
82
+ msg = f"**{name}** is AFK Currently!\n**From :** {time_}"
83
+ if res_ and isinstance(res_, str):
84
+ msg += f"\n**Reason :** {res_}"
85
+ elif res_ and isinstance(res_, Message):
86
+ await event.reply(res_)
87
+ await event.reply(msg)
88
+ ST_SPAM.append(replied.sender_id)
89
+ for ent, text in event.get_entities_text():
90
+ dont_send, entity = None, None
91
+ if isinstance(ent, MessageEntityMentionName):
92
+ c_id = ent.user_id
93
+ elif isinstance(ent, MessageEntityMention):
94
+ c_id = text
95
+ else:
96
+ c_id = None
97
+ if c_id:
98
+ entity = await event.client.get_entity(c_id)
99
+ if entity and entity.id in chat_.keys() and entity.id not in ST_SPAM:
100
+ ST_SPAM.append(entity.id)
101
+ s_der = chat_[entity.id]
102
+ name = get_display_name(entity)
103
+ res_ = s_der["reason"]
104
+ time_ = time_formatter((dt.now() - s_der["time"]).seconds * 1000)
105
+ msg = f"**{name}** is AFK Currently!\n**From :** {time_}"
106
+ if res_ and isinstance(res_, str):
107
+ msg += f"\n**Reason :** {res_}"
108
+ elif res_ and isinstance(res_, Message):
109
+ await event.reply(res_)
110
+ await event.reply(msg)
assistant/manager/misc.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 random
10
+
11
+ import aiohttp
12
+
13
+ from pyUltroid.dB import DEVLIST
14
+ from pyUltroid.fns.admins import admin_check
15
+
16
+ from . import *
17
+
18
+
19
+ @asst_cmd(pattern="decide")
20
+ async def dheh(e):
21
+ text = ["Yes", "NoU", "Maybe", "IDK"]
22
+ text = random.choice(text)
23
+ ri = e.reply_to_msg_id or e.id
24
+ await e.client.send_message(e.chat_id, text, reply_to=ri)
25
+
26
+
27
+ @asst_cmd(pattern="echo( (.*)|$)")
28
+ async def oqha(e):
29
+ if not await admin_check(e):
30
+ return
31
+ if match := e.pattern_match.group(1).strip():
32
+ text = match
33
+ reply_to = e
34
+ elif e.is_reply:
35
+ text = (await e.get_reply_message()).text
36
+ reply_to = e.reply_to_msg_id
37
+ else:
38
+ return await e.eor("What to Echo?", time=5)
39
+ try:
40
+ await e.delete()
41
+ except BaseException as ex:
42
+ LOGS.error(ex)
43
+ await e.client.send_message(e.chat_id, text, reply_to=reply_to)
44
+
45
+
46
+ @asst_cmd(pattern="kickme$")
47
+ async def doit(e):
48
+ if e.sender_id in DEVLIST:
49
+ return await eod(e, "`I will Not Kick You, my Developer..`")
50
+ try:
51
+ await e.client.kick_participant(e.chat_id, e.sender_id)
52
+ except Exception as Fe:
53
+ return await e.eor(str(Fe), time=5)
54
+ await e.eor("Yes, You are right, get out.", time=5)
55
+
56
+
57
+ @asst_cmd(pattern="joke$")
58
+ async def do_joke(e):
59
+ e = await e.get_reply_message() if e.is_reply else e
60
+ link = "https://v2.jokeapi.dev/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&type=single"
61
+ async with aiohttp.ClientSession() as ses:
62
+ async with ses.get(link) as out:
63
+ out = await out.json()
64
+ await e.reply(out["joke"])
assistant/manager/stickermanager.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 random
9
+
10
+ from telethon import errors
11
+ from telethon.errors.rpcerrorlist import StickersetInvalidError
12
+ from telethon.tl.functions.messages import GetStickerSetRequest as GetSticker
13
+ from telethon.tl.functions.messages import UploadMediaRequest
14
+ from telethon.tl.functions.stickers import AddStickerToSetRequest as AddSticker
15
+ from telethon.tl.functions.stickers import CreateStickerSetRequest
16
+ from telethon.tl.types import InputPeerSelf
17
+ from telethon.tl.types import InputStickerSetItem as SetItem
18
+ from telethon.tl.types import InputStickerSetShortName, User
19
+ from telethon.utils import get_display_name, get_input_document
20
+
21
+ from pyUltroid.fns.misc import Quotly
22
+ from pyUltroid.fns.tools import TgConverter
23
+
24
+ from . import LOGS, asst, asst_cmd, udB
25
+
26
+
27
+ @asst_cmd(
28
+ pattern="kang",
29
+ )
30
+ async def kang_cmd(ult):
31
+ sender = await ult.get_sender()
32
+ if not isinstance(sender, User):
33
+ return
34
+ if not ult.is_reply:
35
+ return await ult.eor("`Reply to a sticker/photo..`", time=5)
36
+ reply = await ult.get_reply_message()
37
+ if sender.username:
38
+ pre = sender.username[:4]
39
+ else:
40
+ pre = random.random_string(length=3)
41
+ animated, dl, video = None, None, None
42
+ try:
43
+ emoji = ult.text.split(maxsplit=1)[1]
44
+ except IndexError:
45
+ emoji = None
46
+ if reply.sticker:
47
+ file = get_input_document(reply.sticker)
48
+ emoji = emoji or reply.file.emoji
49
+ name = reply.file.name
50
+ if name.endswith(".tgs"):
51
+ animated = True
52
+ dl = await reply.download_media()
53
+ elif name.endswith(".webm"):
54
+ video = True
55
+ dl = await reply.download_media()
56
+ elif reply.photo:
57
+ dl = await reply.download_media()
58
+ name = "sticker.webp"
59
+ image = TgConverter.resize_photo_sticker(dl)
60
+ image.save(name, "WEBP")
61
+ elif reply.text:
62
+ dl = await Quotly().create_quotly(reply)
63
+ else:
64
+ return await ult.eor("`Reply to sticker or text to add it in your pack...`")
65
+ if not emoji:
66
+ emoji = "🏵"
67
+ if dl:
68
+ upl = await ult.client.upload_file(dl)
69
+ file = get_input_document(
70
+ await ult.client(UploadMediaRequest(InputPeerSelf(), upl))
71
+ )
72
+ get_ = udB.get_key("STICKERS") or {}
73
+ type_ = "anim" if animated else "static"
74
+ if not get_.get(ult.sender_id) or not get_.get(ult.sender_id, {}).get(type_):
75
+ sn = f"{pre}_{ult.sender_id}"
76
+ title = f"{get_display_name(sender)}'s Kang Pack"
77
+ if animated:
78
+ type_ = "anim"
79
+ sn += "_anim"
80
+ title += " (Animated)"
81
+ elif video:
82
+ type_ = "vid"
83
+ sn += "_vid"
84
+ title += " (Video)"
85
+ sn += f"_by_{asst.me.username}"
86
+ try:
87
+ await asst(GetSticker(InputStickerSetShortName(sn), hash=0))
88
+ sn = sn.replace(str(ult.sender_id), f"{ult.sender_id}_{ult.id}")
89
+ except StickersetInvalidError:
90
+ pass
91
+ try:
92
+ pack = await ult.client(
93
+ CreateStickerSetRequest(
94
+ user_id=sender.id,
95
+ title=title,
96
+ short_name=sn,
97
+ stickers=[SetItem(file, emoji=emoji)],
98
+ videos=video,
99
+ animated=animated,
100
+ software="@TeamUltroid",
101
+ )
102
+ )
103
+ except Exception as er:
104
+ return await ult.eor(str(er))
105
+ sn = pack.set.short_name
106
+ if not get_.get(ult.sender_id):
107
+ get_.update({ult.sender_id: {type_: [sn]}})
108
+ else:
109
+ get_[ult.sender_id].update({type_: [sn]})
110
+ udB.set_key("STICKERS", get_)
111
+ return await ult.reply(
112
+ f"**Kanged Successfully!\nEmoji :** {emoji}\n**Link :** [Click Here](https://t.me/addstickers/{sn})"
113
+ )
114
+ name = get_[ult.sender_id][type_][-1]
115
+ try:
116
+ await asst(GetSticker(InputStickerSetShortName(name), hash=0))
117
+ except StickersetInvalidError:
118
+ get_[ult.sender_id][type_].remove(name)
119
+ try:
120
+ await asst(
121
+ AddSticker(InputStickerSetShortName(name), SetItem(file, emoji=emoji))
122
+ )
123
+ except (errors.StickerpackStickersTooMuchError, errors.StickersTooMuchError):
124
+ sn = f"{pre}{ult.sender_id}_{ult.id}"
125
+ title = f"{get_display_name(sender)}'s Kang Pack"
126
+ if animated:
127
+ sn += "_anim"
128
+ title += " (Animated)"
129
+ elif video:
130
+ sn += "_vid"
131
+ title += "(Video)"
132
+ sn += f"_by_{asst.me.username}"
133
+ try:
134
+ pack = await ult.client(
135
+ CreateStickerSetRequest(
136
+ user_id=sender.id,
137
+ title=title,
138
+ short_name=sn,
139
+ stickers=[SetItem(file, emoji=emoji)],
140
+ animated=animated,
141
+ )
142
+ )
143
+ except Exception as er:
144
+ return await ult.eor(str(er))
145
+ get_[ult.sender_id][type_].append(pack.set.short_name)
146
+ udB.set_key("STICKERS", get_)
147
+ return await ult.reply(
148
+ f"**Created New Kang Pack!\nEmoji :** {emoji}\n**Link :** [Click Here](https://t.me/addstickers/{sn})"
149
+ )
150
+ except Exception as er:
151
+ LOGS.exception(er)
152
+ return await ult.reply(str(er))
153
+ await ult.reply(
154
+ f"Sticker Added to Pack Successfully\n**Link :** [Click Here](https://t.me/addstickers/{name})"
155
+ )
156
+
157
+
158
+ @asst_cmd(pattern="listpack")
159
+ async def do_magic(ult):
160
+ ko = udB.get_key("STICKERS") or {}
161
+ if not ko.get(ult.sender_id):
162
+ return await ult.reply("No Sticker Pack Found!")
163
+ al_ = []
164
+ ul = ko[ult.sender_id]
165
+ for _ in ul.keys():
166
+ al_.extend(ul[_])
167
+ msg = "• **Stickers Owned by You!**\n\n"
168
+ for _ in al_:
169
+ try:
170
+ pack = await ult.client(GetSticker(InputStickerSetShortName(_), hash=0))
171
+ msg += f"• [{pack.set.title}](https://t.me/addstickers/{_})\n"
172
+ except StickerSetInvalidError:
173
+ if ul.get("anim") and _ in ul["anim"]:
174
+ ul["anim"].remove(_)
175
+ elif ul.get("vid") and _ in ul["vid"]:
176
+ ul["vid"].remove(_)
177
+ else:
178
+ ul["static"].remove(_)
179
+ udB.set_key("STICKERS", ko)
180
+ await ult.reply(msg)
assistant/pmbot.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # https://github.com/xditya/TeleBot/blob/master/telebot/plugins/mybot/pmbot/incoming.py
9
+
10
+ # --------------------------------------- Imports -------------------------------------------- #
11
+
12
+ import os
13
+
14
+ from telethon.errors.rpcerrorlist import UserNotParticipantError
15
+ from telethon.tl.custom import Button
16
+ from telethon.tl.functions.channels import GetFullChannelRequest
17
+ from telethon.tl.functions.messages import GetFullChatRequest
18
+ from telethon.tl.types import Channel, Chat
19
+ from telethon.utils import get_display_name
20
+
21
+ from pyUltroid.dB.base import KeyManager
22
+ from pyUltroid.dB.botchat_db import *
23
+ from pyUltroid.fns.helper import inline_mention
24
+
25
+ from . import *
26
+
27
+ botb = KeyManager("BOTBLS", cast=list)
28
+ FSUB = udB.get_key("PMBOT_FSUB")
29
+ CACHE = {}
30
+ # --------------------------------------- Incoming -------------------------------------------- #
31
+
32
+
33
+ @asst_cmd(
34
+ load=AST_PLUGINS,
35
+ incoming=True,
36
+ func=lambda e: e.is_private and not botb.contains(e.sender_id),
37
+ )
38
+ async def on_new_mssg(event):
39
+ who = event.sender_id
40
+ # doesn't reply to that user anymore
41
+ if event.text.startswith("/") or who == OWNER_ID:
42
+ return
43
+ if FSUB:
44
+ MSG = ""
45
+ BTTS = []
46
+ for chat in FSUB:
47
+ try:
48
+ await event.client.get_permissions(chat, event.sender_id)
49
+ except UserNotParticipantError:
50
+ if not MSG:
51
+ MSG += get_string("pmbot_1")
52
+ try:
53
+ uri = ""
54
+ TAHC_ = await event.client.get_entity(chat)
55
+ if hasattr(TAHC_, "username") and TAHC_.username:
56
+ uri = f"t.me/{TAHC_.username}"
57
+ elif CACHE.get(chat):
58
+ uri = CACHE[chat]
59
+ else:
60
+ if isinstance(TAHC_, Channel):
61
+ FUGB = await event.client(GetFullChannelRequest(chat))
62
+ elif isinstance(TAHC_, Chat):
63
+ FUGB = await event.client(GetFullChatRequest(chat))
64
+ else:
65
+ return
66
+ if FUGB.full_chat.exported_invite:
67
+ CACHE[chat] = FUGB.full_chat.exported_invite.link
68
+ uri = CACHE[chat]
69
+ BTTS.append(Button.url(get_display_name(TAHC_), uri))
70
+ except Exception as er:
71
+ LOGS.exception(f"Error On PmBot Force Sub!\n - {chat} \n{er}")
72
+ if MSG and BTTS:
73
+ return await event.reply(MSG, buttons=BTTS)
74
+ xx = await event.forward_to(OWNER_ID)
75
+ if event.fwd_from:
76
+ await xx.reply(f"From {inline_mention(event.sender)} [`{event.sender_id}`]")
77
+ add_stuff(xx.id, who)
78
+
79
+
80
+ # --------------------------------------- Outgoing -------------------------------------------- #
81
+
82
+
83
+ @asst_cmd(
84
+ load=AST_PLUGINS,
85
+ from_users=[OWNER_ID],
86
+ incoming=True,
87
+ func=lambda e: e.is_private and e.is_reply,
88
+ )
89
+ async def on_out_mssg(event):
90
+ x = event.reply_to_msg_id
91
+ to_user = get_who(x)
92
+ if event.text.startswith("/who"):
93
+ try:
94
+ k = await asst.get_entity(to_user)
95
+ photu = await event.client.download_profile_photo(k.id)
96
+ await event.reply(
97
+ f"• **Name :** {get_display_name(k)}\n• **ID :** `{k.id}`\n• **Link :** {inline_mention(k)}",
98
+ file=photu,
99
+ )
100
+ if photu:
101
+ os.remove(photu)
102
+ return
103
+ except BaseException as er:
104
+ return await event.reply(f"**ERROR : **{str(er)}")
105
+ elif event.text.startswith("/"):
106
+ return
107
+ if to_user:
108
+ await asst.send_message(to_user, event.message)
109
+
110
+
111
+ # --------------------------------------- Ban/Unban -------------------------------------------- #
112
+
113
+
114
+ @asst_cmd(
115
+ pattern="ban",
116
+ load=AST_PLUGINS,
117
+ from_users=[OWNER_ID],
118
+ func=lambda x: x.is_private,
119
+ )
120
+ async def banhammer(event):
121
+ if not event.is_reply:
122
+ return await event.reply(get_string("pmbot_2"))
123
+ target = get_who(event.reply_to_msg_id)
124
+ if botb.contains(target):
125
+ return await event.reply(get_string("pmbot_3"))
126
+
127
+ botb.add(target)
128
+ await event.reply(f"#BAN\nUser : {target}")
129
+ await asst.send_message(target, get_string("pmbot_4"))
130
+
131
+
132
+ @asst_cmd(
133
+ pattern="unban",
134
+ load=AST_PLUGINS,
135
+ from_users=[OWNER_ID],
136
+ func=lambda x: x.is_private,
137
+ )
138
+ async def unbanhammer(event):
139
+ if not event.is_reply:
140
+ return await event.reply(get_string("pmbot_5"))
141
+ target = get_who(event.reply_to_msg_id)
142
+ if not botb.contains(target):
143
+ return await event.reply(get_string("pmbot_6"))
144
+
145
+ botb.remove(target)
146
+ await event.reply(f"#UNBAN\nUser : {target}")
147
+ await asst.send_message(target, get_string("pmbot_7"))
148
+
149
+
150
+ # --------------------------------------- END -------------------------------------------- #
assistant/start.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 datetime import datetime
9
+
10
+ from pytz import timezone as tz
11
+ from telethon import Button, events
12
+ from telethon.errors.rpcerrorlist import MessageDeleteForbiddenError
13
+ from telethon.utils import get_display_name
14
+
15
+ from pyUltroid._misc import SUDO_M, owner_and_sudos
16
+ from pyUltroid.dB.base import KeyManager
17
+ from pyUltroid.fns.helper import inline_mention
18
+ from strings import get_string
19
+
20
+ from . import *
21
+
22
+ Owner_info_msg = udB.get_key("BOT_INFO_START")
23
+ custom_info = True
24
+ if Owner_info_msg is None:
25
+ custom_info = False
26
+ Owner_info_msg = f"""
27
+ **Owner** - {OWNER_NAME}
28
+ **OwnerID** - `{OWNER_ID}`
29
+
30
+ **Message Forwards** - {udB.get_key("PMBOT")}
31
+
32
+ **Ultroid [v{ultroid_version}](https://github.com/TeamUltroid/Ultroid), powered by @TeamUltroid**
33
+ """
34
+
35
+
36
+ _settings = [
37
+ [
38
+ Button.inline("API Kᴇʏs", data="cbs_apiset"),
39
+ Button.inline("Pᴍ Bᴏᴛ", data="cbs_chatbot"),
40
+ ],
41
+ [
42
+ Button.inline("Aʟɪᴠᴇ", data="cbs_alvcstm"),
43
+ Button.inline("PᴍPᴇʀᴍɪᴛ", data="cbs_ppmset"),
44
+ ],
45
+ [
46
+ Button.inline("Fᴇᴀᴛᴜʀᴇs", data="cbs_otvars"),
47
+ Button.inline("VC Sᴏɴɢ Bᴏᴛ", data="cbs_vcb"),
48
+ ],
49
+ [Button.inline("« Bᴀᴄᴋ", data="mainmenu")],
50
+ ]
51
+
52
+ _start = [
53
+ [
54
+ Button.inline("Lᴀɴɢᴜᴀɢᴇ 🌐", data="lang"),
55
+ Button.inline("Sᴇᴛᴛɪɴɢs ⚙️", data="setter"),
56
+ ],
57
+ [
58
+ Button.inline("Sᴛᴀᴛs ✨", data="stat"),
59
+ Button.inline("Bʀᴏᴀᴅᴄᴀsᴛ 📻", data="bcast"),
60
+ ],
61
+ [Button.inline("TɪᴍᴇZᴏɴᴇ 🌎", data="tz")],
62
+ ]
63
+
64
+
65
+ @callback("ownerinfo")
66
+ async def own(event):
67
+ msg = Owner_info_msg.format(
68
+ mention=event.sender.mention, me=inline_mention(ultroid_bot.me)
69
+ )
70
+ if custom_info:
71
+ msg += "\n\n• Powered by **@TeamUltroid**"
72
+ await event.edit(
73
+ msg,
74
+ buttons=[Button.inline("Close", data="closeit")],
75
+ link_preview=False,
76
+ )
77
+
78
+
79
+ @callback("closeit")
80
+ async def closet(lol):
81
+ try:
82
+ await lol.delete()
83
+ except MessageDeleteForbiddenError:
84
+ await lol.answer("MESSAGE_TOO_OLD", alert=True)
85
+
86
+
87
+ @asst_cmd(pattern="start( (.*)|$)", forwards=False, func=lambda x: not x.is_group)
88
+ async def ultroid(event):
89
+ args = event.pattern_match.group(1).strip()
90
+ keym = KeyManager("BOT_USERS", cast=list)
91
+ if not keym.contains(event.sender_id) and event.sender_id not in owner_and_sudos():
92
+ keym.add(event.sender_id)
93
+ kak_uiw = udB.get_key("OFF_START_LOG")
94
+ if not kak_uiw or kak_uiw != True:
95
+ msg = f"{inline_mention(event.sender)} `[{event.sender_id}]` started your [Assistant bot](@{asst.me.username})."
96
+ buttons = [[Button.inline("Info", "itkkstyo")]]
97
+ if event.sender.username:
98
+ buttons[0].append(
99
+ Button.mention(
100
+ "User", await event.client.get_input_entity(event.sender_id)
101
+ )
102
+ )
103
+ await event.client.send_message(
104
+ udB.get_key("LOG_CHANNEL"), msg, buttons=buttons
105
+ )
106
+ if event.sender_id not in SUDO_M.fullsudos:
107
+ ok = ""
108
+ me = inline_mention(ultroid_bot.me)
109
+ mention = inline_mention(event.sender)
110
+ if args and args != "set":
111
+ await get_stored_file(event, args)
112
+ if not udB.get_key("STARTMSG"):
113
+ if udB.get_key("PMBOT"):
114
+ ok = "You can contact my master using this bot!!\n\nSend your Message, I will Deliver it To Master."
115
+ await event.reply(
116
+ f"Hey there {mention}, this is Ultroid Assistant of {me}!\n\n{ok}",
117
+ file=udB.get_key("STARTMEDIA"),
118
+ buttons=[Button.inline("Info.", data="ownerinfo")]
119
+ if Owner_info_msg
120
+ else None,
121
+ )
122
+ else:
123
+ await event.reply(
124
+ udB.get_key("STARTMSG").format(me=me, mention=mention),
125
+ file=udB.get_key("STARTMEDIA"),
126
+ buttons=[Button.inline("Info.", data="ownerinfo")]
127
+ if Owner_info_msg
128
+ else None,
129
+ )
130
+ else:
131
+ name = get_display_name(event.sender)
132
+ if args == "set":
133
+ await event.reply(
134
+ "Choose from the below options -",
135
+ buttons=_settings,
136
+ )
137
+ elif args:
138
+ await get_stored_file(event, args)
139
+ else:
140
+ await event.reply(
141
+ get_string("ast_3").format(name),
142
+ buttons=_start,
143
+ )
144
+
145
+
146
+ @callback("itkkstyo", owner=True)
147
+ async def ekekdhdb(e):
148
+ text = f"When New Visitor will visit your Assistant Bot. You will get this log message!\n\nTo Disable : {HNDLR}setdb OFF_START_LOG True"
149
+ await e.answer(text, alert=True)
150
+
151
+
152
+ @callback("mainmenu", owner=True, func=lambda x: not x.is_group)
153
+ async def ultroid(event):
154
+ await event.edit(
155
+ get_string("ast_3").format(OWNER_NAME),
156
+ buttons=_start,
157
+ )
158
+
159
+
160
+ @callback("stat", owner=True)
161
+ async def botstat(event):
162
+ ok = len(udB.get_key("BOT_USERS") or [])
163
+ msg = """Ultroid Assistant - Stats
164
+ Total Users - {}""".format(
165
+ ok,
166
+ )
167
+ await event.answer(msg, cache_time=0, alert=True)
168
+
169
+
170
+ @callback("bcast", owner=True)
171
+ async def bdcast(event):
172
+ keym = KeyManager("BOT_USERS", cast=list)
173
+ total = keym.count()
174
+ await event.edit(f"• Broadcast to {total} users.")
175
+ async with event.client.conversation(OWNER_ID) as conv:
176
+ await conv.send_message(
177
+ "Enter your broadcast message.\nUse /cancel to stop the broadcast.",
178
+ )
179
+ response = await conv.get_response()
180
+ if response.message == "/cancel":
181
+ return await conv.send_message("Cancelled!!")
182
+ success = 0
183
+ fail = 0
184
+ await conv.send_message(f"Starting a broadcast to {total} users...")
185
+ start = datetime.now()
186
+ for i in keym.get():
187
+ try:
188
+ await asst.send_message(int(i), response)
189
+ success += 1
190
+ except BaseException:
191
+ fail += 1
192
+ end = datetime.now()
193
+ time_taken = (end - start).seconds
194
+ await conv.send_message(
195
+ f"""
196
+ **Broadcast completed in {time_taken} seconds.**
197
+ Total Users in Bot - {total}
198
+ **Sent to** : `{success} users.`
199
+ **Failed for** : `{fail} user(s).`""",
200
+ )
201
+
202
+
203
+ @callback("setter", owner=True)
204
+ async def setting(event):
205
+ await event.edit(
206
+ "Choose from the below options -",
207
+ buttons=_settings,
208
+ )
209
+
210
+
211
+ @callback("tz", owner=True)
212
+ async def timezone_(event):
213
+ await event.delete()
214
+ pru = event.sender_id
215
+ var = "TIMEZONE"
216
+ name = "Timezone"
217
+ async with event.client.conversation(pru) as conv:
218
+ await conv.send_message(
219
+ "Send Your TimeZone From This List [Check From Here](http://www.timezoneconverter.com/cgi-bin/findzone.tzc)"
220
+ )
221
+ response = conv.wait_event(events.NewMessage(chats=pru))
222
+ response = await response
223
+ themssg = response.message.message
224
+ if themssg == "/cancel":
225
+ return await conv.send_message(
226
+ "Cancelled!!",
227
+ buttons=get_back_button("mainmenu"),
228
+ )
229
+ try:
230
+ tz(themssg)
231
+ await setit(event, var, themssg)
232
+ await conv.send_message(
233
+ f"{name} changed to {themssg}\n",
234
+ buttons=get_back_button("mainmenu"),
235
+ )
236
+ except BaseException:
237
+ await conv.send_message(
238
+ "Wrong TimeZone, Try again",
239
+ buttons=get_back_button("mainmenu"),
240
+ )
assistant/ytdl.py ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 re
11
+
12
+ try:
13
+ from PIL import Image
14
+ except ImportError:
15
+ Image = None
16
+ from telethon import Button
17
+ from telethon.errors.rpcerrorlist import FilePartLengthInvalidError, MediaEmptyError
18
+ from telethon.tl.types import DocumentAttributeAudio, DocumentAttributeVideo
19
+ from telethon.tl.types import InputWebDocument as wb
20
+
21
+ from pyUltroid.fns.helper import (
22
+ bash,
23
+ fast_download,
24
+ humanbytes,
25
+ numerize,
26
+ time_formatter,
27
+ )
28
+ from pyUltroid.fns.ytdl import dler, get_buttons, get_formats
29
+
30
+ from . import LOGS, asst, callback, in_pattern, udB
31
+
32
+ try:
33
+ from youtubesearchpython import VideosSearch
34
+ except ImportError:
35
+ LOGS.info("'youtubesearchpython' not installed!")
36
+ VideosSearch = None
37
+
38
+
39
+ ytt = "https://graph.org/file/afd04510c13914a06dd03.jpg"
40
+ _yt_base_url = "https://www.youtube.com/watch?v="
41
+ BACK_BUTTON = {}
42
+
43
+
44
+ @in_pattern("yt", owner=True)
45
+ async def _(event):
46
+ try:
47
+ string = event.text.split(" ", maxsplit=1)[1]
48
+ except IndexError:
49
+ fuk = event.builder.article(
50
+ title="Search Something",
51
+ thumb=wb(ytt, 0, "image/jpeg", []),
52
+ text="**YᴏᴜTᴜʙᴇ Sᴇᴀʀᴄʜ**\n\nYou didn't search anything",
53
+ buttons=Button.switch_inline(
54
+ "Sᴇᴀʀᴄʜ Aɢᴀɪɴ",
55
+ query="yt ",
56
+ same_peer=True,
57
+ ),
58
+ )
59
+ await event.answer([fuk])
60
+ return
61
+ results = []
62
+ search = VideosSearch(string, limit=50)
63
+ nub = search.result()
64
+ nibba = nub["result"]
65
+ for v in nibba:
66
+ ids = v["id"]
67
+ link = _yt_base_url + ids
68
+ title = v["title"]
69
+ duration = v["duration"]
70
+ views = v["viewCount"]["short"]
71
+ publisher = v["channel"]["name"]
72
+ published_on = v["publishedTime"]
73
+ description = (
74
+ v["descriptionSnippet"][0]["text"]
75
+ if v.get("descriptionSnippet")
76
+ and len(v["descriptionSnippet"][0]["text"]) < 500
77
+ else "None"
78
+ )
79
+ thumb = f"https://i.ytimg.com/vi/{ids}/hqdefault.jpg"
80
+ text = f"**Title: [{title}]({link})**\n\n"
81
+ text += f"`Description: {description}\n\n"
82
+ text += f"「 Duration: {duration} 」\n"
83
+ text += f"「 Views: {views} 」\n"
84
+ text += f"「 Publisher: {publisher} 」\n"
85
+ text += f"「 Published on: {published_on} 」`"
86
+ desc = f"{title}\n{duration}"
87
+ file = wb(thumb, 0, "image/jpeg", [])
88
+ buttons = [
89
+ [
90
+ Button.inline("Audio", data=f"ytdl:audio:{ids}"),
91
+ Button.inline("Video", data=f"ytdl:video:{ids}"),
92
+ ],
93
+ [
94
+ Button.switch_inline(
95
+ "Sᴇᴀʀᴄʜ Aɢᴀɪɴ",
96
+ query="yt ",
97
+ same_peer=True,
98
+ ),
99
+ Button.switch_inline(
100
+ "Sʜᴀʀᴇ",
101
+ query=f"yt {string}",
102
+ same_peer=False,
103
+ ),
104
+ ],
105
+ ]
106
+ BACK_BUTTON.update({ids: {"text": text, "buttons": buttons}})
107
+ results.append(
108
+ await event.builder.article(
109
+ type="photo",
110
+ title=title,
111
+ description=desc,
112
+ thumb=file,
113
+ content=file,
114
+ text=text,
115
+ include_media=True,
116
+ buttons=buttons,
117
+ ),
118
+ )
119
+ await event.answer(results[:50])
120
+
121
+
122
+ @callback(
123
+ re.compile(
124
+ "ytdl:(.*)",
125
+ ),
126
+ owner=True,
127
+ )
128
+ async def _(e):
129
+ _e = e.pattern_match.group(1).strip().decode("UTF-8")
130
+ _lets_split = _e.split(":")
131
+ _ytdl_data = await dler(e, _yt_base_url + _lets_split[1])
132
+ _data = get_formats(_lets_split[0], _lets_split[1], _ytdl_data)
133
+ _buttons = get_buttons(_data)
134
+ _text = (
135
+ "`Select Your Format.`"
136
+ if _buttons
137
+ else "`Error downloading from YouTube.\nTry Restarting your bot.`"
138
+ )
139
+
140
+ await e.edit(_text, buttons=_buttons)
141
+
142
+
143
+ @callback(
144
+ re.compile(
145
+ "ytdownload:(.*)",
146
+ ),
147
+ owner=True,
148
+ )
149
+ async def _(event):
150
+ url = event.pattern_match.group(1).strip().decode("UTF-8")
151
+ lets_split = url.split(":")
152
+ vid_id = lets_split[2]
153
+ link = _yt_base_url + vid_id
154
+ format = lets_split[1]
155
+ try:
156
+ ext = lets_split[3]
157
+ except IndexError:
158
+ ext = "mp3"
159
+ if lets_split[0] == "audio":
160
+ opts = {
161
+ "format": "bestaudio",
162
+ "addmetadata": True,
163
+ "key": "FFmpegMetadata",
164
+ "prefer_ffmpeg": True,
165
+ "geo_bypass": True,
166
+ "outtmpl": f"%(id)s.{ext}",
167
+ "logtostderr": False,
168
+ "postprocessors": [
169
+ {
170
+ "key": "FFmpegExtractAudio",
171
+ "preferredcodec": ext,
172
+ "preferredquality": format,
173
+ },
174
+ {"key": "FFmpegMetadata"},
175
+ ],
176
+ }
177
+
178
+ ytdl_data = await dler(event, link, opts, True)
179
+ title = ytdl_data["title"]
180
+ if ytdl_data.get("artist"):
181
+ artist = ytdl_data["artist"]
182
+ elif ytdl_data.get("creator"):
183
+ artist = ytdl_data["creator"]
184
+ elif ytdl_data.get("channel"):
185
+ artist = ytdl_data["channel"]
186
+ views = numerize(ytdl_data.get("view_count")) or 0
187
+ thumb, _ = await fast_download(ytdl_data["thumbnail"], filename=f"{vid_id}.jpg")
188
+
189
+ likes = numerize(ytdl_data.get("like_count")) or 0
190
+ duration = ytdl_data.get("duration") or 0
191
+ description = (
192
+ ytdl_data["description"]
193
+ if len(ytdl_data["description"]) < 100
194
+ else ytdl_data["description"][:100]
195
+ )
196
+ description = description or "None"
197
+ filepath = f"{vid_id}.{ext}"
198
+ if not os.path.exists(filepath):
199
+ filepath = f"{filepath}.{ext}"
200
+ size = os.path.getsize(filepath)
201
+ file, _ = await event.client.fast_uploader(
202
+ filepath,
203
+ filename=f"{title}.{ext}",
204
+ show_progress=True,
205
+ event=event,
206
+ to_delete=True,
207
+ )
208
+
209
+ attributes = [
210
+ DocumentAttributeAudio(
211
+ duration=int(duration),
212
+ title=title,
213
+ performer=artist,
214
+ ),
215
+ ]
216
+ elif lets_split[0] == "video":
217
+ opts = {
218
+ "format": str(format),
219
+ "addmetadata": True,
220
+ "key": "FFmpegMetadata",
221
+ "prefer_ffmpeg": True,
222
+ "geo_bypass": True,
223
+ "outtmpl": f"%(id)s.{ext}",
224
+ "logtostderr": False,
225
+ "postprocessors": [{"key": "FFmpegMetadata"}],
226
+ }
227
+
228
+ ytdl_data = await dler(event, link, opts, True)
229
+ title = ytdl_data["title"]
230
+ if ytdl_data.get("artist"):
231
+ artist = ytdl_data["artist"]
232
+ elif ytdl_data.get("creator"):
233
+ artist = ytdl_data["creator"]
234
+ elif ytdl_data.get("channel"):
235
+ artist = ytdl_data["channel"]
236
+ views = numerize(ytdl_data.get("view_count")) or 0
237
+ thumb, _ = await fast_download(ytdl_data["thumbnail"], filename=f"{vid_id}.jpg")
238
+
239
+ try:
240
+ Image.open(thumb).save(thumb, "JPEG")
241
+ except Exception as er:
242
+ LOGS.exception(er)
243
+ thumb = None
244
+ description = (
245
+ ytdl_data["description"]
246
+ if len(ytdl_data["description"]) < 100
247
+ else ytdl_data["description"][:100]
248
+ )
249
+ likes = numerize(ytdl_data.get("like_count")) or 0
250
+ hi, wi = ytdl_data.get("height") or 720, ytdl_data.get("width") or 1280
251
+ duration = ytdl_data.get("duration") or 0
252
+ filepath = f"{vid_id}.mkv"
253
+ if not os.path.exists(filepath):
254
+ filepath = f"{filepath}.webm"
255
+ size = os.path.getsize(filepath)
256
+ file, _ = await event.client.fast_uploader(
257
+ filepath,
258
+ filename=f"{title}.mkv",
259
+ show_progress=True,
260
+ event=event,
261
+ to_delete=True,
262
+ )
263
+
264
+ attributes = [
265
+ DocumentAttributeVideo(
266
+ duration=int(duration),
267
+ w=wi,
268
+ h=hi,
269
+ supports_streaming=True,
270
+ ),
271
+ ]
272
+ description = description if description != "" else "None"
273
+ text = f"**Title: [{title}]({_yt_base_url}{vid_id})**\n\n"
274
+ text += f"`📝 Description: {description}\n\n"
275
+ text += f"「 Duration: {time_formatter(int(duration)*1000)} 」\n"
276
+ text += f"「 Artist: {artist} 」\n"
277
+ text += f"「 Views: {views} 」\n"
278
+ text += f"「 Likes: {likes} 」\n"
279
+ text += f"「 Size: {humanbytes(size)} 」`"
280
+ button = Button.switch_inline("Search More", query="yt ", same_peer=True)
281
+ try:
282
+ await event.edit(
283
+ text,
284
+ file=file,
285
+ buttons=button,
286
+ attributes=attributes,
287
+ thumb=thumb,
288
+ )
289
+ except (FilePartLengthInvalidError, MediaEmptyError):
290
+ file = await asst.send_message(
291
+ udB.get_key("LOG_CHANNEL"),
292
+ text,
293
+ file=file,
294
+ buttons=button,
295
+ attributes=attributes,
296
+ thumb=thumb,
297
+ )
298
+ await event.edit(text, file=file.media, buttons=button)
299
+ await bash(f"rm {vid_id}.jpg")
300
+
301
+
302
+ @callback(re.compile("ytdl_back:(.*)"), owner=True)
303
+ async def ytdl_back(event):
304
+ id_ = event.data_match.group(1).decode("utf-8")
305
+ if not BACK_BUTTON.get(id_):
306
+ return await event.answer("Query Expired! Search again 🔍")
307
+ await event.edit(**BACK_BUTTON[id_])
docker-compose.yml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ services:
2
+ worker:
3
+ build: .
4
+ environment:
5
+ REDIS_URI: $REDIS_URI
6
+ REDIS_PASSWORD: $REDIS_PASSWORD
7
+ SESSION: $SESSION
8
+ API_ID: $API_ID # defaults to None
9
+ API_HASH: $API_HASH # defaults to None
10
+ MONGO_URI: $MONGO_URI # defaults to None
11
+ BOT_TOKEN: $BOT_TOKEN # Not mandatory
12
+ LOG_CHANNEL: $LOG_CHANNEL # Not mandatory
13
+ DATABASE_URL: $DATABASE_URL # defaults to None
14
+ OKTETO_TOKEN: $OKTETO_TOKEN
installer.sh ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ REPO="https://github.com/TeamUltroid/Ultroid.git"
4
+ CURRENT_DIR="$(pwd)"
5
+ ENV_FILE_PATH=".env"
6
+ DIR="/root/TeamUltroid"
7
+
8
+ while [ $# -gt 0 ]; do
9
+ case "$1" in
10
+ --dir=*)
11
+ DIR="${1#*=}" || DIR="/root/TeamUltroid"
12
+ ;;
13
+ --branch=*)
14
+ BRANCH="${1#*=}" || BRANCH="main"
15
+ ;;
16
+ --env-file=*)
17
+ ENV_FILE_PATH="${1#*=}" || ENV_FILE_PATH=".env"
18
+ ;;
19
+ --no-root)
20
+ NO_ROOT=true
21
+ ;;
22
+ *)
23
+ echo "Unknown parameter passed: $1"
24
+ exit 1
25
+ ;;
26
+ esac
27
+ shift
28
+ done
29
+
30
+ check_dependencies() {
31
+ # check if debian
32
+ echo "Checking dependencies..."
33
+ # read file with root access
34
+ if ! [[ $(ls -l "/etc/sudoers" | cut -d " " -f1) =~ "r" ]]; then
35
+ # check dependencies if installed
36
+ echo -e "Root access not found. Checking if dependencies are installed." >&2
37
+ if ! [ -x "$(command -v python3)" ] || ! [ -x "$(command -v python)" ]; then
38
+ echo -e "Python3 isn't installed. Please install python3.8 or higher to run this bot." >&2
39
+ exit 1
40
+ fi
41
+ if [ $(python3 -c "import sys; print(sys.version_info[1])") -lt 8 ] || [ $(python -c "import sys; print(sys.version_info[1])") -lt 8 ]; then
42
+ echo -e "Python 3.8 or higher is required to run this bot." >&2
43
+ exit 1
44
+ fi
45
+ # check if any of ffmpeg, mediainfo, neofetch, git is not installed
46
+ if ! command -v ffmpeg &>/dev/null || ! command -v mediainfo &>/dev/null || ! command -v neofetch &>/dev/null || ! command -v git &>/dev/null; then
47
+ echo -e "Some dependencies aren't installed. Please install ffmpeg, mediainfo, neofetch and git to run this bot." >&2
48
+ exit 1
49
+ fi
50
+ fi
51
+ if [ -x "$(command -v apt-get)" ]; then
52
+ echo -e "Installing dependencies..."
53
+ # check if any of ffmpeg, mediainfo, neofetch, git is not installed via dpkg
54
+ if dpkg -l | grep -q ffmpeg || dpkg -l | grep -q mediainfo || dpkg -l | grep -q neofetch || dpkg -l | grep -q git; then
55
+ sudo apt-get -qq -o=Dpkg::Use-Pty=0 update
56
+ sudo apt-get install -qq -o=Dpkg::Use-Pty=0 python3 python3-pip ffmpeg mediainfo neofetch git -y
57
+ fi
58
+ elif [ -x "$(command -v pacman)" ]; then
59
+ echo -e "Installing dependencies..."
60
+ if pacman -Q | grep -q ffmpeg || pacman -Q | grep -q mediainfo || pacman -Q | grep -q neofetch || pacman -Q | grep -q git; then
61
+ sudo pacman -Sy python python-pip git ffmpeg mediainfo neofetch --noconfirm
62
+ fi
63
+ else
64
+ echo -e "Unknown OS. Checking if dependecies are installed" >&2
65
+ if ! [ -x "$(command -v python3)" ] || ! [ -x "$(command -v python)" ]; then
66
+ echo -e "Python3 isn't installed. Please install python3.8 or higher to run this bot." >&2
67
+ exit 1
68
+ fi
69
+ if [ $(python3 -c "import sys; print(sys.version_info[1])") -lt 8 ] || [ $(python -c "import sys; print(sys.version_info[1])") -lt 8 ]; then
70
+ echo -e "Python 3.8 or higher is required to run this bot." >&2
71
+ exit 1
72
+ fi
73
+ if ! command -v ffmpeg &>/dev/null || ! command -v mediainfo &>/dev/null || ! command -v neofetch &>/dev/null || ! command -v git &>/dev/null; then
74
+ echo -e "Some dependencies aren't installed. Please install ffmpeg, mediainfo, neofetch and git to run this bot." >&2
75
+ exit 1
76
+ fi
77
+ fi
78
+ }
79
+
80
+ check_python() {
81
+ # check if python is installed
82
+ if ! command -v python3 &>/dev/null; then
83
+ echo -e "Python3 isn't installed. Please install python3.8 or higher to run this bot."
84
+ exit 1
85
+ elif ! command -v python &>/dev/null; then
86
+ echo -e "Python3 isn't installed. Please install python3.8 or higher to run this bot."
87
+ exit 1
88
+ fi
89
+ if [ $(python3 -c "import sys; print(sys.version_info[1])") -lt 8 ]; then
90
+ echo -e "Python 3.8 or higher is required to run this bot."
91
+ exit 1
92
+ elif [ $(python -c "import sys; print(sys.version_info[1])") -lt 3 ]; then
93
+ if [ $(python -c "import sys; print(sys.version_info[1])") -lt 8 ]; then
94
+ echo -e "Python 3.8 or higher is required to run this bot."
95
+ exit 1
96
+ fi
97
+ fi
98
+ }
99
+
100
+ clone_repo() {
101
+ # check if pyultroid, startup, plugins folders exist
102
+ cd $DIR
103
+ if [ -d $DIR ]; then
104
+ if [ -d $DIR/.git ]; then
105
+ echo -e "Updating Ultroid ${BRANCH}... "
106
+ cd $DIR
107
+ git pull
108
+ currentbranch="$(git rev-parse --abbrev-ref HEAD)"
109
+ if [ ! $BRANCH ]; then
110
+ export BRANCH=$currentbranch
111
+ fi
112
+ case $currentbranch in
113
+ $BRANCH)
114
+ # do nothing
115
+ ;;
116
+ *)
117
+ echo -e "Switching to branch ${BRANCH}... "
118
+ echo -e $currentbranch
119
+ git checkout $BRANCH
120
+ ;;
121
+ esac
122
+ else
123
+ rm -rf $DIR
124
+ exit 1
125
+ fi
126
+ if [ -d "addons" ]; then
127
+ cd addons
128
+ git pull
129
+ fi
130
+ return
131
+ else
132
+ if [ ! $BRANCH ]; then
133
+ export BRANCH="main"
134
+ fi
135
+ mkdir -p $DIR
136
+ echo -e "Cloning Ultroid ${BRANCH}... "
137
+ git clone -b $BRANCH $REPO $DIR
138
+ fi
139
+ }
140
+
141
+ install_requirements() {
142
+ pip3 install -q --upgrade pip
143
+ echo -e "\n\nInstalling requirements... "
144
+ pip3 install -q --no-cache-dir -r $DIR/requirements.txt
145
+ pip3 install -q -r $DIR/resources/startup/optional-requirements.txt
146
+ }
147
+
148
+ railways_dep() {
149
+ if [ $RAILWAY_STATIC_URL ]; then
150
+ echo -e "Installing YouTube dependency... "
151
+ pip3 install -q yt-dlp
152
+ fi
153
+ }
154
+
155
+ misc_install() {
156
+ if [ $SETUP_PLAYWRIGHT ]
157
+ then
158
+ echo -e "Installing playwright."
159
+ pip3 install playwright
160
+ playwright install
161
+ fi
162
+ if [ $OKTETO_TOKEN ]; then
163
+ echo -e "Installing Okteto-CLI... "
164
+ curl https://get.okteto.com -sSfL | sh
165
+ elif [ $VCBOT ]; then
166
+ if [ -d $DIR/vcbot ]; then
167
+ cd $DIR/vcbot
168
+ git pull
169
+ else
170
+ echo -e "Cloning VCBOT.."
171
+ git clone https://github.com/TeamUltroid/VcBot $DIR/vcbot
172
+ fi
173
+ pip3 install pytgcalls==3.0.0.dev23 && pip3 install av -q --no-binary av
174
+ fi
175
+ }
176
+
177
+ dep_install() {
178
+ echo -e "\n\nInstalling DB Requirement..."
179
+ if [ $MONGO_URI ]; then
180
+ echo -e " Installing MongoDB Requirements..."
181
+ pip3 install -q pymongo[srv]
182
+ elif [ $DATABASE_URL ]; then
183
+ echo -e " Installing PostgreSQL Requirements..."
184
+ pip3 install -q psycopg2-binary
185
+ elif [ $REDIS_URI ]; then
186
+ echo -e " Installing Redis Requirements..."
187
+ pip3 install -q redis hiredis
188
+ fi
189
+ }
190
+
191
+ main() {
192
+ echo -e "Starting Ultroid Setup..."
193
+ if [ -d "pyUltroid" ] && [ -d "resources" ] && [ -d "plugins" ]; then
194
+ DIR=$CURRENT_DIR
195
+ fi
196
+ if [ -f $ENV_FILE_PATH ]
197
+ then
198
+ set -a
199
+ source <(cat $ENV_FILE_PATH | sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
200
+ set +a
201
+ cp $ENV_FILE_PATH .env
202
+ fi
203
+ (check_dependencies)
204
+ (check_python)
205
+ (clone_repo)
206
+ (install_requirements)
207
+ (railways_dep)
208
+ (dep_install)
209
+ (misc_install)
210
+ echo -e "\n\nSetup Completed."
211
+ }
212
+
213
+ if [ $NO_ROOT ]; then
214
+ echo -e "Running with non root"
215
+ main
216
+ return 0
217
+ elif [ -t 0 ]; then
218
+ unameOut="$(uname -s)"
219
+ case "${unameOut}" in
220
+ Linux*) machine=Linux;;
221
+ Darwin*) machine=Mac;;
222
+ CYGWIN*) machine=Cygwin;;
223
+ MINGW*) machine=MinGw;;
224
+ *) machine="UNKNOWN:${unameOut}"
225
+ esac
226
+ if machine != "Linux"; then
227
+ echo -e "This script is only for Linux. Please use the Windows installer."
228
+ exit 1
229
+ fi
230
+ # check if sudo is installed
231
+ if ! command -v sudo &>/dev/null; then
232
+ echo -e "Sudo isn't installed. Please install sudo to run this bot."
233
+ exit 1
234
+ fi
235
+ sudo echo "Sudo permission granted."
236
+ main
237
+ else
238
+ echo "Not an interactive terminal, skipping sudo."
239
+ # run main function
240
+ main
241
+ fi
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,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
25
+ • ANTHROPIC_MODEL
26
+ • GEMINI_MODEL
27
+ • DEEPSEEK_MODEL
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/v1/models/gemini-pro:generateContent",
40
+ "deepseek": "https://api.deepseek.com/chat/completions"
41
+ }
42
+
43
+ DEFAULT_MODELS = {
44
+ "gpt": "gpt-3.5-turbo",
45
+ "antr": "claude-3-opus-20240229",
46
+ "gemini": "gemini-pro",
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
+ params = {"key": api_key}
167
+ data = {
168
+ "contents": [{
169
+ "parts": [{"text": prompt}]
170
+ }]
171
+ }
172
+ response = await async_searcher(
173
+ ENDPOINTS[provider],
174
+ params=params,
175
+ headers=headers,
176
+ post=True,
177
+ json=data,
178
+ re_json=True
179
+ )
180
+ text = response["candidates"][0]["content"]["parts"][0]["text"]
181
+ if not stream:
182
+ yield text
183
+ return
184
+
185
+ # Simulate streaming by yielding chunks
186
+ words = text.split()
187
+ buffer = []
188
+ for word in words:
189
+ buffer.append(word)
190
+ if len(' '.join(buffer)) > 20: # Adjust chunk size as needed
191
+ yield ' '.join(buffer) + ' '
192
+ buffer = []
193
+ if buffer:
194
+ yield ' '.join(buffer)
195
+
196
+ elif provider == "deepseek":
197
+ headers["Authorization"] = f"Bearer {api_key}"
198
+ data = {
199
+ "model": model,
200
+ "messages": [{"role": "user", "content": prompt}],
201
+ "stream": stream
202
+ }
203
+ if not stream:
204
+ response = await async_searcher(
205
+ ENDPOINTS[provider],
206
+ headers=headers,
207
+ post=True,
208
+ json=data,
209
+ re_json=True
210
+ )
211
+ yield response["choices"][0]["message"]["content"]
212
+ return
213
+
214
+ async with aiohttp.ClientSession() as session:
215
+ async with session.post(
216
+ ENDPOINTS[provider],
217
+ headers=headers,
218
+ json=data
219
+ ) as resp:
220
+ async for line in resp.content:
221
+ if line:
222
+ try:
223
+ json_line = json.loads(line.decode('utf-8').strip())
224
+ if 'choices' in json_line and json_line['choices']:
225
+ content = json_line['choices'][0].get('delta', {}).get('content', '')
226
+ if content:
227
+ yield content
228
+ except Exception:
229
+ continue
230
+
231
+ except Exception as e:
232
+ LOGS.exception(e)
233
+ yield f"Error: {str(e)}"
234
+
235
+
236
+ @ultroid_cmd(pattern="gemini( (.*)|$)")
237
+ async def gemini_ai(event):
238
+ """Use Google Gemini"""
239
+ prompt = event.pattern_match.group(1).strip()
240
+ if not prompt:
241
+ return await event.eor("❌ Please provide a prompt!")
242
+
243
+ api_key = udB.get_key("GEMINI_API_KEY")
244
+ if not api_key:
245
+ return await event.eor("⚠️ Please set Gemini API key using `setdb GEMINI_API_KEY your_api_key`")
246
+
247
+ msg = await event.eor("🤔 Thinking...")
248
+ model = get_model("gemini")
249
+
250
+ header = (
251
+ "🤖 **Google Gemini**\n"
252
+ f"**Model:** `{model}`\n"
253
+ "➖➖➖➖➖➖➖➖➖➖\n\n"
254
+ f"**🔍 Prompt:**\n{prompt}\n\n"
255
+ "**💡 Response:**\n"
256
+ )
257
+
258
+ if event.client.me.bot:
259
+ await msg.edit(header)
260
+ response = ""
261
+ async for chunk in get_ai_response("gemini", prompt, api_key, stream=True):
262
+ response += chunk
263
+ try:
264
+ await msg.edit(header + response)
265
+ except Exception:
266
+ pass
267
+ else:
268
+ response = ""
269
+ async for chunk in get_ai_response("gemini", prompt, api_key, stream=True):
270
+ response += chunk
271
+ try:
272
+ await msg.edit(header + response)
273
+ except Exception:
274
+ pass
275
+
276
+ @ultroid_cmd(pattern="antr( (.*)|$)")
277
+ async def anthropic_ai(event):
278
+ """Use Anthropic Claude"""
279
+ prompt = event.pattern_match.group(1).strip()
280
+ if not prompt:
281
+ return await event.eor("❌ Please provide a prompt!")
282
+
283
+ api_key = udB.get_key("ANTHROPIC_KEY")
284
+ if not api_key:
285
+ return await event.eor("⚠️ Please set Anthropic API key using `setdb ANTHROPIC_KEY your_api_key`")
286
+
287
+ msg = await event.eor("🤔 Thinking...")
288
+ model = get_model("antr")
289
+
290
+ formatted_response = (
291
+ "🧠 **Anthropic Claude**\n"
292
+ f"**Model:** `{model}`\n"
293
+ "➖➖➖➖➖➖➖➖➖➖\n\n"
294
+ f"**🔍 Prompt:**\n{prompt}\n\n"
295
+ f"**💡 Response:**\n"
296
+ )
297
+
298
+ if event.client.me.bot:
299
+ await msg.edit(formatted_response)
300
+ response = ""
301
+ async for chunk in get_ai_response("antr", prompt, api_key, stream=True):
302
+ response += chunk
303
+ try:
304
+ await msg.edit(formatted_response + response)
305
+ except Exception:
306
+ pass
307
+ else:
308
+ response = ""
309
+ async for chunk in get_ai_response("antr", prompt, api_key, stream=True):
310
+ response += chunk
311
+ try:
312
+ await msg.edit(formatted_response + response)
313
+ except Exception:
314
+ pass
315
+
316
+ @ultroid_cmd(pattern="gpt( (.*)|$)")
317
+ async def openai_ai(event):
318
+ """Use OpenAI GPT"""
319
+ prompt = event.pattern_match.group(1).strip()
320
+ if not prompt:
321
+ return await event.eor("❌ Please provide a prompt!")
322
+
323
+ api_key = udB.get_key("OPENAI_API_KEY")
324
+ if not api_key:
325
+ return await event.eor("⚠️ Please set GPT API key using `setdb OPENAI_API_KEY your_api_key`")
326
+
327
+ msg = await event.eor("🤔 Thinking...")
328
+ model = get_model("gpt")
329
+
330
+ header = (
331
+ "🌟 **OpenAI GPT**\n"
332
+ f"**Model:** `{model}`\n"
333
+ "➖➖➖➖➖➖➖➖➖➖\n\n"
334
+ f"**🔍 Prompt:**\n{prompt}\n\n"
335
+ "**💡 Response:**\n"
336
+ )
337
+
338
+ if event.client.me.bot:
339
+ await msg.edit(header)
340
+ response = ""
341
+ async for chunk in get_ai_response("gpt", prompt, api_key, stream=True):
342
+ response += chunk
343
+ try:
344
+ await msg.edit(header + response)
345
+ except Exception:
346
+ pass
347
+ else:
348
+ response =""
349
+ async for chunk in get_ai_response("gpt", prompt, api_key, stream=True):
350
+ response += chunk
351
+ try:
352
+ await msg.edit(header + response)
353
+ except Exception:
354
+ pass
355
+
356
+ @ultroid_cmd(pattern="deepseek( (.*)|$)")
357
+ async def deepseek_ai(event):
358
+ """Use DeepSeek AI"""
359
+ prompt = event.pattern_match.group(1).strip()
360
+ if not prompt:
361
+ return await event.eor("❌ Please provide a prompt!")
362
+
363
+ api_key = udB.get_key("DEEPSEEK_API_KEY")
364
+ if not api_key:
365
+ return await event.eor("⚠️ Please set DeepSeek API key using `setdb DEEPSEEK_API_KEY your_api_key`")
366
+
367
+ msg = await event.eor("🤔 Thinking...")
368
+ model = get_model("deepseek")
369
+
370
+ formatted_response = (
371
+ "🤖 **DeepSeek AI**\n"
372
+ f"**Model:** `{model}`\n"
373
+ "➖➖➖➖➖➖➖➖➖➖\n\n"
374
+ f"**🔍 Prompt:**\n{prompt}\n\n"
375
+ f"**💡 Response:**\n"
376
+ )
377
+
378
+ if event.client.me.bot:
379
+ await msg.edit(formatted_response)
380
+ response = ""
381
+ async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True):
382
+ response += chunk
383
+ try:
384
+ await msg.edit(formatted_response + response)
385
+ except Exception:
386
+ pass
387
+ else:
388
+ response = ""
389
+ async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True):
390
+ response += chunk
391
+
392
+ try:
393
+ await msg.edit(formatted_response + response)
394
+ except Exception:
395
+ pass
396
+
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,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
14
+ from telethon.tl.functions.photos import UploadProfilePhotoRequest
15
+
16
+ from pyUltroid.fns.helper import download_file
17
+ from pyUltroid.fns.tools import get_google_images
18
+
19
+ from . import LOGS, get_help, get_string, udB, ultroid_bot, ultroid_cmd
20
+
21
+ __doc__ = get_help("help_autopic")
22
+
23
+
24
+ @ultroid_cmd(pattern="autopic( (.*)|$)")
25
+ async def autopic(e):
26
+ search = e.pattern_match.group(1).strip()
27
+ if udB.get_key("AUTOPIC") and not search:
28
+ udB.del_key("AUTOPIC")
29
+ return await e.eor(get_string("autopic_5"))
30
+ if not search:
31
+ return await e.eor(get_string("autopic_1"), time=5)
32
+ e = await e.eor(get_string("com_1"))
33
+ gi = googleimagesdownload()
34
+ args = {
35
+ "keywords": search,
36
+ "limit": 50,
37
+ "format": "jpg",
38
+ "output_directory": "./resources/downloads/",
39
+ }
40
+ try:
41
+ pth = await gi.download(args)
42
+ ok = pth[0][search]
43
+ except Exception as er:
44
+ LOGS.exception(er)
45
+ return await e.eor(str(er))
46
+ if not ok:
47
+ return await e.eor(get_string("autopic_2").format(search), time=5)
48
+ await e.eor(get_string("autopic_3").format(search))
49
+ udB.set_key("AUTOPIC", search)
50
+ SLEEP_TIME = udB.get_key("SLEEP_TIME") or 1221
51
+ while True:
52
+ for lie in ok:
53
+ if udB.get_key("AUTOPIC") != search:
54
+ return
55
+ file = await e.client.upload_file(lie)
56
+ await e.client(UploadProfilePhotoRequest(file))
57
+ await asyncio.sleep(SLEEP_TIME)
58
+ shuffle(ok)
59
+
60
+
61
+ if search := udB.get_key("AUTOPIC"):
62
+ images = {}
63
+ sleep = udB.get_key("SLEEP_TIME") or 1221
64
+
65
+ async def autopic_func():
66
+ search = udB.get_key("AUTOPIC")
67
+ if images.get(search) is None:
68
+ images[search] = await get_google_images(search)
69
+ if not images.get(search):
70
+ return
71
+ img = random.choice(images[search])
72
+ filee = await download_file(img["original"], "resources/downloads/autopic.jpg")
73
+ file = await ultroid_bot.upload_file(filee)
74
+ await ultroid_bot(UploadProfilePhotoRequest(file))
75
+ os.remove(filee)
76
+
77
+ try:
78
+ from apscheduler.schedulers.asyncio import AsyncIOScheduler
79
+
80
+ schedule = AsyncIOScheduler()
81
+ schedule.add_job(autopic_func, "interval", seconds=sleep)
82
+ schedule.start()
83
+ except ModuleNotFoundError as er:
84
+ 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/blacklist.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_blacklist")
11
+
12
+
13
+ from pyUltroid.dB.blacklist_db import (
14
+ add_blacklist,
15
+ get_blacklist,
16
+ list_blacklist,
17
+ rem_blacklist,
18
+ )
19
+
20
+ from . import events, get_string, udB, ultroid_bot, ultroid_cmd
21
+
22
+
23
+ @ultroid_cmd(pattern="blacklist( (.*)|$)", admins_only=True)
24
+ async def af(e):
25
+ wrd = e.pattern_match.group(1).strip()
26
+ chat = e.chat_id
27
+ if not (wrd):
28
+ return await e.eor(get_string("blk_1"), time=5)
29
+ wrd = e.text[11:]
30
+ heh = wrd.split(" ")
31
+ for z in heh:
32
+ add_blacklist(int(chat), z.lower())
33
+ ultroid_bot.add_handler(blacklist, events.NewMessage(incoming=True))
34
+ await e.eor(get_string("blk_2").format(wrd))
35
+
36
+
37
+ @ultroid_cmd(pattern="remblacklist( (.*)|$)", admins_only=True)
38
+ async def rf(e):
39
+ wrd = e.pattern_match.group(1).strip()
40
+ chat = e.chat_id
41
+ if not wrd:
42
+ return await e.eor(get_string("blk_3"), time=5)
43
+ wrd = e.text[14:]
44
+ heh = wrd.split(" ")
45
+ for z in heh:
46
+ rem_blacklist(int(chat), z.lower())
47
+ await e.eor(get_string("blk_4").format(wrd))
48
+
49
+
50
+ @ultroid_cmd(pattern="listblacklist$", admins_only=True)
51
+ async def lsnote(e):
52
+ if x := list_blacklist(e.chat_id):
53
+ sd = get_string("blk_5")
54
+ return await e.eor(sd + x)
55
+ await e.eor(get_string("blk_6"))
56
+
57
+
58
+ async def blacklist(e):
59
+ if x := get_blacklist(e.chat_id):
60
+ text = e.text.lower().split()
61
+ if any((z in text) for z in x):
62
+ try:
63
+ await e.delete()
64
+ except BaseException:
65
+ pass
66
+
67
+
68
+ if udB.get_key("BLACKLIST_DB"):
69
+ ultroid_bot.add_handler(blacklist, events.NewMessage(incoming=True))
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):
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")