Spaces:
Sleeping
Sleeping
sdmadhav commited on
Commit ·
80dbdee
1
Parent(s): a79db0f
aff
Browse files- afc_care.session +0 -0
- app.py +106 -0
- madhav.session +0 -0
afc_care.session
ADDED
|
Binary file (41 kB). View file
|
|
|
app.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import asyncio
|
| 3 |
+
from telethon.sync import TelegramClient
|
| 4 |
+
from telethon.errors import FloodWaitError
|
| 5 |
+
from telethon.tl.types import ChannelParticipantsAdmins
|
| 6 |
+
|
| 7 |
+
# 🔐 Your fixed API credentials
|
| 8 |
+
api_id = 29716085
|
| 9 |
+
api_hash = '75073ce12878f4e510bbaae6642a9752'
|
| 10 |
+
|
| 11 |
+
# Get user's channels
|
| 12 |
+
async def fetch_channels(session_name):
|
| 13 |
+
async with TelegramClient(session_name, api_id, api_hash) as client:
|
| 14 |
+
dialogs = await client.get_dialogs(limit=100)
|
| 15 |
+
channels = [d for d in dialogs if d.is_channel]
|
| 16 |
+
return [(ch.name, ch.id) for ch in channels]
|
| 17 |
+
|
| 18 |
+
# Remove non-admin, non-whitelisted users
|
| 19 |
+
async def remove_members(session_name, channel_id, allowed_user_ids_str):
|
| 20 |
+
output = []
|
| 21 |
+
|
| 22 |
+
allowed_ids = {int(uid.strip()) for uid in allowed_user_ids_str.split(',') if uid.strip().isdigit()}
|
| 23 |
+
|
| 24 |
+
async with TelegramClient(session_name, api_id, api_hash) as client:
|
| 25 |
+
me = await client.get_me()
|
| 26 |
+
output.append(f"Logged in as: {me.username or me.first_name} (ID: {me.id})")
|
| 27 |
+
|
| 28 |
+
channel = await client.get_entity(channel_id)
|
| 29 |
+
output.append(f"Selected Channel: {channel.title}")
|
| 30 |
+
|
| 31 |
+
admins = await client.get_participants(channel, filter=ChannelParticipantsAdmins)
|
| 32 |
+
admin_ids = {admin.id for admin in admins}
|
| 33 |
+
exclude_ids = admin_ids.union({me.id}, allowed_ids)
|
| 34 |
+
|
| 35 |
+
output.append(f"Total admins (including you): {len(admin_ids)}")
|
| 36 |
+
output.append(f"Starting to remove members (excluding {len(exclude_ids)} allowed users)...")
|
| 37 |
+
|
| 38 |
+
total_removed = 0
|
| 39 |
+
|
| 40 |
+
async for user in client.iter_participants(channel):
|
| 41 |
+
if user.id in exclude_ids:
|
| 42 |
+
continue
|
| 43 |
+
|
| 44 |
+
try:
|
| 45 |
+
await client.kick_participant(channel, user.id)
|
| 46 |
+
output.append(f"Removed: {user.first_name or user.username} (ID: {user.id})")
|
| 47 |
+
total_removed += 1
|
| 48 |
+
except FloodWaitError as e:
|
| 49 |
+
output.append(f"FloodWait: Need to wait {e.seconds} seconds.")
|
| 50 |
+
await asyncio.sleep(e.seconds)
|
| 51 |
+
try:
|
| 52 |
+
await client.kick_participant(channel, user.id)
|
| 53 |
+
output.append(f"Retried and removed: {user.first_name or user.username} (ID: {user.id})")
|
| 54 |
+
total_removed += 1
|
| 55 |
+
except Exception as e2:
|
| 56 |
+
output.append(f"Retry failed for {user.id}: {e2}")
|
| 57 |
+
except Exception as e:
|
| 58 |
+
output.append(f"Could not remove {user.id}: {e}")
|
| 59 |
+
|
| 60 |
+
output.append(f"\n✅ Done. Total members removed: {total_removed}")
|
| 61 |
+
return "\n".join(output)
|
| 62 |
+
|
| 63 |
+
# Wrappers
|
| 64 |
+
def list_channels(session_name):
|
| 65 |
+
return asyncio.run(fetch_channels(session_name))
|
| 66 |
+
|
| 67 |
+
def cleanup_members(session_name, channel_id, allowed_users):
|
| 68 |
+
return asyncio.run(remove_members(session_name, channel_id, allowed_users))
|
| 69 |
+
|
| 70 |
+
# Gradio UI
|
| 71 |
+
with gr.Blocks() as app:
|
| 72 |
+
gr.Markdown("## 🧹 Telegram Channel Cleaner (Telethon + Gradio)")
|
| 73 |
+
|
| 74 |
+
session_name = gr.Textbox(label="Session Name", placeholder="e.g., mysession")
|
| 75 |
+
|
| 76 |
+
get_channels_btn = gr.Button("📥 Fetch Channels")
|
| 77 |
+
channel_dropdown = gr.Dropdown(label="Select Channel", choices=[], interactive=True)
|
| 78 |
+
|
| 79 |
+
allowed_users = gr.Textbox(
|
| 80 |
+
label="Allowed User IDs (comma-separated)",
|
| 81 |
+
placeholder="e.g., 12345678,87654321"
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
run_button = gr.Button("🚀 Run Cleanup")
|
| 85 |
+
output_log = gr.Textbox(label="Output Log", lines=20, interactive=False)
|
| 86 |
+
|
| 87 |
+
def populate_channels(session_name):
|
| 88 |
+
try:
|
| 89 |
+
channels = list_channels(session_name)
|
| 90 |
+
return gr.update(choices=[(name, id) for name, id in channels], value=None)
|
| 91 |
+
except Exception as e:
|
| 92 |
+
return gr.update(choices=[], value=None), f"❌ Error: {e}"
|
| 93 |
+
|
| 94 |
+
get_channels_btn.click(
|
| 95 |
+
populate_channels,
|
| 96 |
+
inputs=[session_name],
|
| 97 |
+
outputs=[channel_dropdown]
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
run_button.click(
|
| 101 |
+
cleanup_members,
|
| 102 |
+
inputs=[session_name, channel_dropdown, allowed_users],
|
| 103 |
+
outputs=[output_log]
|
| 104 |
+
)
|
| 105 |
+
|
| 106 |
+
app.launch()
|
madhav.session
ADDED
|
Binary file (49.2 kB). View file
|
|
|