File size: 13,390 Bytes
9db4ada
0e31799
f0f9ad9
 
11ae35a
 
 
89a7a7a
 
30b876d
87abec5
11ae35a
30b876d
11ae35a
f0f9ad9
30b876d
83fe5dc
0d887f0
3925c05
af1662b
 
42a7e92
184520d
 
42a7e92
b51521e
ef4e395
 
 
6cef7ec
ef4e395
 
 
 
 
6cef7ec
ef4e395
 
 
 
 
 
0364f1a
6cef7ec
0364f1a
ef4e395
 
 
 
 
 
 
 
 
 
 
 
82a6804
14c8b0e
6e5ac37
af1662b
0364f1a
fa6f4d3
30b876d
 
 
 
 
 
 
 
 
 
af1662b
30b876d
d5348c6
fa6f4d3
af1662b
9015bc5
fa6f4d3
af1662b
fa6f4d3
 
0d887f0
30b876d
83fe5dc
0d887f0
30b876d
0d887f0
18c86d3
30b876d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18c86d3
0d887f0
6cef7ec
c62ca93
26ed39a
92b81e1
c62ca93
83fe5dc
63ad048
83fe5dc
63ad048
83fe5dc
63ad048
c62ca93
de34607
63ad048
 
83fe5dc
63ad048
89ad488
89ef22e
fac74eb
 
 
f87a0c5
3fb2204
6cef7ec
f87a0c5
6cef7ec
f87a0c5
6cef7ec
f87a0c5
6cef7ec
f87a0c5
6cef7ec
f87a0c5
6cef7ec
 
 
 
 
 
af1662b
18c86d3
0e31799
18c86d3
0e31799
26ed39a
30b876d
18c86d3
30b876d
 
 
 
 
bb1bfd1
 
 
 
 
 
30b876d
8657278
26ed39a
18c86d3
26ed39a
30b876d
18c86d3
 
 
af1662b
18c86d3
42a7e92
 
fa6f4d3
89a7a7a
0d887f0
9015bc5
 
89a7a7a
0a49271
89a7a7a
 
0a49271
89a7a7a
6cef7ec
89a7a7a
 
6cef7ec
9015bc5
 
 
 
89a7a7a
 
 
0a49271
89a7a7a
6cef7ec
89a7a7a
 
 
9015bc5
 
 
0d887f0
6cef7ec
7eb17b1
0d887f0
26ed39a
0d887f0
fac74eb
0d887f0
 
 
 
 
fac74eb
c1d601a
3a7618b
18c86d3
 
 
 
 
26ed39a
18c86d3
89ad488
aa46d17
 
b51521e
aa46d17
26ed39a
 
 
ef4e395
18c86d3
b2229d5
5ea462e
18c86d3
 
 
 
42a7e92
 
af1662b
3925c05
7044b8b
 
 
6dcea66
 
f4fa14d
 
6dcea66
f4fa14d
 
af1662b
87abec5
89ad488
87abec5
6fefa14
 
e44597a
14c8b0e
6fefa14
 
 
 
30b876d
 
 
bbd57f9
30b876d
 
 
 
 
bbd57f9
a2a21bb
 
8657278
30b876d
 
 
6fefa14
 
0e31799
7eb17b1
0e31799
 
6fefa14
 
7eb17b1
6e5ac37
 
 
 
 
 
 
 
 
 
 
 
 
 
6dcea66
6cef7ec
 
6dcea66
89ad488
6e5ac37
 
 
 
6fefa14
 
6e5ac37
6fefa14
14c8b0e
af1662b
fa6f4d3
af1662b
6e5ac37
a68f766
7044b8b
6cef7ec
7044b8b
725787c
6e5ac37
 
af1662b
6e5ac37
 
89ad488
6cef7ec
6e5ac37
1ee14ac
6e5ac37
0d887f0
6cef7ec
 
 
6e5ac37
89ad488
6e5ac37
89ad488
5942ba9
 
9015bc5
 
 
5942ba9
 
6c4dae8
5942ba9
6e5ac37
0e31799
7eb17b1
6e5ac37
42a7e92
6e5ac37
 
 
 
 
 
 
 
 
 
 
 
 
 
1ee14ac
6e5ac37
0d887f0
c224902
fac74eb
 
 
6e5ac37
 
 
 
af1662b
0d887f0
a06c0e6
0d887f0
 
af1662b
8a5a595
709df35
096ee5f
709df35
d5348c6
 
423e59b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
import os
from asyncio import sleep
from datetime import datetime
from traceback import format_exc

from pyrogram import enums
from pyrogram.errors import EntityBoundsInvalid, MediaCaptionTooLong, RPCError
from pyrogram.raw.functions.channels import GetFullChannel
from pyrogram.raw.functions.users import GetFullUser
from pyrogram.raw.types import Channel, UserFull, users
from pyrogram.types import Message

from Powers import BDB_URI, LOGGER, OWNER_ID
from Powers.bot_class import Gojo
from Powers.database.antispam_db import GBan
from Powers.database.approve_db import Approve
from Powers.supports import get_support_staff
from Powers.utils.custom_filters import command
from Powers.utils.extract_user import extract_user

gban_db = GBan()

if BDB_URI:
    from Powers.plugins import bday_info

async def count(c: Gojo, chat):
    try:
        administrator = []
        async for admin in c.get_chat_members(
                chat_id=chat, filter=enums.ChatMembersFilter.ADMINISTRATORS
        ):
            administrator.append(admin)
        total_admin = administrator
        bot = []
        async for tbot in c.get_chat_members(
                chat_id=chat, filter=enums.ChatMembersFilter.BOTS
        ):
            bot.append(tbot)

        total_bot = bot
        bot_admin = 0
        ban = []
        async for banned in c.get_chat_members(
                chat, filter=enums.ChatMembersFilter.BANNED
        ):
            ban.append(banned)

        total_banned = ban
        for x in total_admin:
            for y in total_bot:
                if x == y:
                    bot_admin += 1
        total_admin = len(total_admin)
        total_bot = len(total_bot)
        total_banned = len(total_banned)
        return total_bot, total_admin, bot_admin, total_banned
    except Exception as e:
        total_bot = total_admin = bot_admin = total_banned = "`Can't fetch because I am not part of the chat.`"

    return total_bot, total_admin, bot_admin, total_banned


async def user_info(c: Gojo, user, already=False):
    user_all: users.UserFull = await c.invoke(
        GetFullUser(
            id=await c.resolve_peer(user)
        )
    )
    user = await c.get_users(user)
    full_user: UserFull = user_all.full_user
    channel: Channel = user_all.chats
    if user.is_deleted:
        return "Deleted account", None

    
    gbanned, reason_gban = gban_db.get_gban(user.id)
    if gbanned:
        gban = True
        reason = reason_gban
    else:
        gban = False
        reason = "User is not gbanned"

    user_id = user.id
    about = full_user.about
    SUPPORT_STAFF = get_support_staff()
    username = user.username
    full_name = user.full_name
    dc_id = user.dc_id
    is_verified = user.is_verified
    mention = user.mention
    dob = False
    if dob := full_user.birthday:
        dob = datetime(int(dob.year), int(dob.month), int(dob.day)).strftime("%d %B %Y")
    else:
        if BDB_URI:  
            try:      
                if result := bday_info.find_one({"user_id": user}):
                    u_dob = datetime.strptime(result["dob"], "%d/%m/%Y")
                    day = u_dob.day
                    formatted = u_dob.strftime("%B %Y")
                    suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(day % 10, 'th')
                    dob = f"{day}{suffix} {formatted}"
            except:
                pass

    is_restricted = user.is_restricted
    photo_id = user.photo.big_file_id if user.photo else None
    is_support = user_id in SUPPORT_STAFF
    if user_id == c.me.id:
        is_support = "A person is a great support to himself"
    omp = "Hmmm.......Who is that again?"
    if is_support or c.me.id:
        if user_id in get_support_staff("dev"):
            omp = "Dev"
        elif user_id in get_support_staff("sudo"):
            omp = "Sudoer"
        elif user_id in get_support_staff("whitelist"):
            omp = "Whitelist"
        elif user_id == c.me.id:
            omp = "I am the targeted user"
        elif user_id == OWNER_ID:
            omp = "Owner of the bot"
        if user_id in get_support_staff("dev") and user_id == OWNER_ID:
            omp = "Dev and Owner"

    is_scam = user.is_scam
    is_bot = user.is_bot
    is_fake = user.is_fake
    status = user.status
    last_date = "Unable to fetch"
    if is_bot is True:
        last_date = "Targeted user is a bot"
    if status == enums.UserStatus.RECENTLY:
        last_date = "User was seen recently"
    if status == enums.UserStatus.LAST_WEEK:
        last_date = "User was seen last week"
    if status == enums.UserStatus.LAST_MONTH:
        last_date = "User was seen last month"
    if status == enums.UserStatus.LONG_AGO:
        last_date = "User was seen long ago or may be I am blocked by the user  :("
    if status == enums.UserStatus.ONLINE:
        last_date = "User is online"
    if status == enums.UserStatus.OFFLINE:
        try:
            last_date = datetime.fromtimestamp(user.status.date).strftime("%Y-%m-%d %H:%M:%S")
        except Exception:
            last_date = "User is offline"

    caption = f"""
<b><i><u>⚑️ Extracted User info From Telegram ⚑️</b></i></u>

<b>πŸ†” User ID</b>: <code>{user_id}</code>
<b>🫡 Mention</b>: {mention}
<b>πŸ—£ Full Name</b>: <code>{full_name}</code>
<b>πŸ” Username</b>: {("@" + username) if username else "NA"}
<b>✍️ Bio</b>: `{about}`\n"""
    if dob:
        caption += f"<b>πŸŽ‚ Birthday<b>: {dob}\n<b>πŸ§‘β€πŸ’» Support</b>: {is_support}\n"
    else:
        caption += f"<b>πŸ§‘β€πŸ’» Support</b>: {is_support}\n"
    if is_support:
        caption += f"<b>πŸ₯· Support user type</b>: <code>{omp}</code>\n<b>πŸ’£ Gbanned</b>: {gban}\n"
    else:
        caption += f"<b>πŸ’£ Gbanned</b>: {gban}\n"

    if gban:
        caption += f"<b>☠️ Gban reason</b>: <code>{reason}</code>"
    caption += f"""<b>🌐 DC ID</b>: {dc_id}
<b>βœ‹ RESTRICTED</b>: {is_restricted}
<b>βœ… VERIFIED</b>: {is_verified}
<b>❌ FAKE</b> : {is_fake}
<b>⚠️ SCAM</b> : {is_scam}
<b>πŸ€– BOT</b>: {is_bot}
<b>πŸ‘€ Last seen</b>: <code>{last_date}</code>
"""

    return caption, photo_id


async def chat_info(c: Gojo, chat, already=False):
    u_name = False
    if not already:
        try:
            chat = await c.get_chat(chat)
            try:
                chat_r = (await c.resolve_peer(chat.id))
                ll = await c.invoke(
                    GetFullChannel(
                        channel=chat_r
                    )
                )
                u_name = ll.chats[0].usernames
            except Exception:
                pass
        except Exception:
            try:
                chat_r = await c.resolve_peer(chat)
                chat = await c.get_chat(chat_r.channel_id)
                try:
                    ll = await c.invoke(
                        GetFullChannel(
                            channel=chat_r
                        )
                    )
                    u_name = ll.chats[0].usernames
                except Exception:
                    pass
            except KeyError as e:
                caption = f"Failed to find the chat due to\n{e}"
                return caption, None
    chat_id = chat.id
    username = " ".join([f"@{i}" for i in u_name]) if u_name else chat.username
    total_bot, total_admin, total_bot_admin, total_banned = await count(c, chat.id)
    title = chat.title
    type_ = str(chat.type).split(".")[1]
    is_scam = chat.is_scam
    is_fake = chat.is_fake
    description = chat.description
    members = chat.members_count
    is_restricted = chat.is_restricted
    dc_id = chat.dc_id
    photo_id = chat.photo.big_file_id if chat.photo else None
    can_save = chat.has_protected_content
    linked_chat = chat.linked_chat

    caption = f"""
πŸ”° <b>CHAT INFO</b> πŸ”°

<b>πŸ†” ID</b>: <code>{chat_id}</code>
<b>πŸš€ Chat Title</b>: {title}
<b>✨ Chat Type</b>: {type_}
<b>🌐 DataCentre ID</b>: {dc_id}
<b>πŸ” Username</b>: {f"@{username}" if username else "NA"}
<b>⚜️ Administrators</b>: {total_admin}
<b>πŸ€– Bots</b>: {total_bot}
<b>🚫 Banned</b>: {total_banned}
<b>⚜️ Admin πŸ€– Bots</b>: {total_bot_admin}
<b>⁉️ Scam</b>: {is_scam}
<b>❌ Fake</b>: {is_fake}
<b>βœ‹ Restricted</b>: {is_restricted}
<b>πŸ‘¨πŸΏβ€πŸ’» Description</b>: <code>{description}</code>
<b>πŸ‘ͺ Total members</b>: {members}
<b>🚫 Has Protected Content</b>: {can_save}
<b>πŸ”— Linked Chat</b>: <code>{linked_chat.id if linked_chat else "Not Linked"}</code>

"""

    return caption, photo_id


@Gojo.on_message(command(["info", "whois"]))
async def info_func(c: Gojo, message: Message):
    if message.reply_to_message and message.reply_to_message.sender_chat:
        await message.reply_text("This is not a user, but rather a channel. Use `/chinfo` to fetch its information.")
        return
    try:
        user, _, user_name = await extract_user(c, message)
    except Exception as e:
        await message.reply_text(f"Got Some errors failed to fetch user info\n{e}")
        LOGGER.error(e)
        LOGGER.error(format_exc())
        return

    m = await message.reply_text(
        f"Fetching {f'@{user_name}' if user_name else 'user'} info from telegram's database..."
    )

    try:
        info_caption, photo_id = await user_info(c, user)

    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(format_exc())
        return await m.edit(str(e))
    

    status = False
    if m.from_user and (m.chat.id != m.from_user.id):
        try:
            if status:= await m.chat.get_member(user):
                status = str(status.status.value).capitalize()
        except:
            pass
        if not status or status == "Member":
            approved_users = Approve(m.chat.id).check_approve(user)
            if Approve(m.chat.id).check_approve(user):
                status = "Member, Approved"

    if status:
        info_caption += f"<b>πŸ‘₯ Status </b>: {status}"

    if not photo_id:
        await m.delete()
        await sleep(2)
        return await message.reply_text(info_caption, disable_web_page_preview=True)
    photo = await c.download_media(photo_id)

    await m.delete()
    await sleep(2)
    try:
        await message.reply_photo(photo, caption=info_caption, quote=False)
    except MediaCaptionTooLong:
        x = await message.reply_photo(photo)
        try:
            await x.reply_text(info_caption)
        except EntityBoundsInvalid:
            await x.delete()
            await message.reply_text(info_caption)
        except RPCError as rpc:
            await message.reply_text(rpc)
            LOGGER.error(rpc)
            LOGGER.error(format_exc())
    except Exception as e:
        if e == "User not found ! Error: 'InputPeerChannel' object has no attribute 'user_id'":
            await m.reply_text(
                "Looks like you are trying to fetch info of a chat not an user. In that case please use /chinfo")
            return

        await message.reply_text(text=e)
        LOGGER.error(e)
        LOGGER.error(format_exc())

    os.remove(photo)

    return


@Gojo.on_message(command(["chinfo", "chatinfo", "chat_info"]))
async def chat_info_func(c: Gojo, message: Message):
    splited = message.text.split()
    if len(splited) == 1:
        if message.reply_to_message and message.reply_to_message.sender_chat:
            chat = message.reply_to_message.sender_chat.id
        else:
            chat = message.chat.id

    else:
        chat = splited[1]

    try:
        chat = int(chat)
    except Exception as ef:
        if "invalid literal for int() with base 10:" not in str(ef):
            return await message.reply_text(
                f"Got and exception {ef}\n**Usage:**/chinfo [USERNAME|ID]"
            )

        chat = str(chat)
        if chat.startswith("https://"):
            chat = '@' + chat.split("/")[-1]
    m = await message.reply_text(
        "Fetching chat info of chat from telegram's database....."
    )

    try:
        info_caption, photo_id = await chat_info(c, chat=chat)
        if info_caption.startswith("Failed to find the chat due"):
            await message.reply_text(info_caption)
            return
    except Exception as e:
        await m.delete()
        await sleep(0.5)
        return await message.reply_text(f"**GOT AN ERROR:**\n {e}")
    if not photo_id:
        await m.delete()
        await sleep(2)
        return await message.reply_text(info_caption, disable_web_page_preview=True)

    photo = await c.download_media(photo_id)
    await m.delete()
    await sleep(2)
    try:
        await message.reply_photo(photo, caption=info_caption, quote=False)
    except MediaCaptionTooLong:
        x = await message.reply_photo(photo)
        try:
            await x.reply_text(info_caption)
        except EntityBoundsInvalid:
            await x.delete()
            await message.reply_text(info_caption)
        except RPCError as rpc:
            await message.reply_text(rpc)
            LOGGER.error(rpc)
            LOGGER.error(format_exc())
    except Exception as e:
        await message.reply_text(text=e)
        LOGGER.error(e)
        LOGGER.error(format_exc())

    os.remove(photo)

    return


__PLUGIN__ = "info"
__alt_name__ = [
    "info",
    "chinfo",
]

__HELP__ = """
**Information**

β€’ /info - To get info about the user
β€’ /chinfo - To get info about the chat
"""