Muttered3 commited on
Commit
0621c65
Β·
verified Β·
1 Parent(s): 45ef928

Update bot.py

Browse files
Files changed (1) hide show
  1. bot.py +173 -0
bot.py CHANGED
@@ -126,6 +126,154 @@ async def proxy_cmd(client, message):
126
 
127
  await msg.edit_text(f"βœ… Saved **{len(working)}** working proxies to memory.", reply_markup=get_dynamic_menu())
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  # --- UI CALLBACKS ---
130
  @app.on_callback_query(is_admin)
131
  async def button_handler(client, query):
@@ -160,6 +308,19 @@ async def button_handler(client, query):
160
  log.info("Scanner Stopped")
161
  await query.edit_message_text("⏹ Scanner Stopped", reply_markup=get_dynamic_menu())
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  elif data == "load_words":
164
  await query.edit_message_text("⏳ Processing and loading chunk into memory...")
165
  try:
@@ -182,6 +343,18 @@ async def button_handler(client, query):
182
  kb = InlineKeyboardMarkup([[InlineKeyboardButton("πŸ”„ Refresh", callback_data="refresh_status")], [InlineKeyboardButton("Β« Back", callback_data="back_main")]])
183
  try: await query.edit_message_text(msg, reply_markup=kb)
184
  except MessageNotModified: pass
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
  elif data == "export_files":
187
  await query.edit_message_text("⏳ Preparing files from disk...")
 
126
 
127
  await msg.edit_text(f"βœ… Saved **{len(working)}** working proxies to memory.", reply_markup=get_dynamic_menu())
128
 
129
+ @app.on_message(filters.command("upload") & is_admin)
130
+ async def upload_cmd(client, message):
131
+ # Support both replying to a file, OR sending the file with the command as a caption
132
+ target_message = message if message.document else message.reply_to_message
133
+
134
+ if not target_message or not target_message.document:
135
+ return await message.reply_text("⚠️ Send a `.txt` file with the caption `/upload`, or reply to a file with `/upload`.")
136
+
137
+ msg = await message.reply_text("⏳ Downloading `words.txt`...")
138
+
139
+ try:
140
+ # Pyrogram downloads to a hidden folder. We capture the exact path.
141
+ file_path = await target_message.download()
142
+
143
+ # Move it to the root directory where the bot is looking for it and overwrite the old one
144
+ if os.path.exists("words.txt"):
145
+ os.remove("words.txt")
146
+ os.replace(file_path, "words.txt")
147
+
148
+ await msg.edit_text("βœ… **Uploaded!**\nGo to System Settings -> Load Words to add them to the queue.", reply_markup=get_dynamic_menu())
149
+ except Exception as e:
150
+ await msg.edit_text(f"❌ **Upload Error:** `{str(e)}`")
151
+ log.error(f"Upload Error: {str(e)}")
152
+
153
+ @app.on_message(filters.command("check") & is_admin)
154
+ async def check_cmd(client, message):
155
+ if len(message.command) < 2: return await message.reply_text("Usage: `/check <word>`")
156
+ target = message.command[1].lower()
157
+ msg = await message.reply_text(f"πŸ“Έ Taking live screenshot of `@{target}` on Fragment...")
158
+
159
+ url = f"https://fragment.com/username/{target}"
160
+ img_filename = None
161
+
162
+ try:
163
+ def take_screenshot():
164
+ from html2image import Html2Image
165
+ hti = Html2Image(
166
+ browser_executable='/usr/bin/chromium',
167
+ custom_flags=['--no-sandbox', '--disable-gpu', '--hide-scrollbars', '--disable-dev-shm-usage']
168
+ )
169
+ hti.size = (1000, 750)
170
+ name = f"{target}_fragment.png"
171
+ hti.screenshot(url=url, save_as=name)
172
+ return name
173
+
174
+ img_filename = await asyncio.to_thread(take_screenshot)
175
+ await message.reply_document(document=img_filename, caption=f"**Live Web Snapshot:** `@{target}`")
176
+ await msg.delete()
177
+
178
+ except Exception as e:
179
+ try: await msg.edit_text(f"❌ **Screenshot Error:**\n`{str(e)}`")
180
+ except: pass
181
+ finally:
182
+ if img_filename and os.path.exists(img_filename):
183
+ os.remove(img_filename)
184
+
185
+ @app.on_message(filters.command("html") & is_admin)
186
+ async def html_cmd(client, message):
187
+ if len(message.command) < 2: return await message.reply_text("Usage: `/html <word>`")
188
+ target = message.command[1].lower()
189
+ msg = await message.reply_text(f"πŸ” Fetching raw HTML for `@{target}` via Chrome Impersonation...")
190
+
191
+ url = f"https://fragment.com/username/{target}"
192
+
193
+ try:
194
+ async with AsyncSession(impersonate="chrome120") as session:
195
+ resp = await session.get(url, timeout=15, allow_redirects=True)
196
+ html_text = resp.text
197
+ status_code = resp.status_code
198
+ final_url = str(resp.url)
199
+
200
+ f = io.BytesIO(html_text.encode('utf-8'))
201
+ f.name = f"{target}_fragment.html"
202
+ f.seek(0)
203
+
204
+ caption = (f"πŸ“„ **Raw Response for** `@{target}`\n"
205
+ f"**Requested URL:** `{url}`\n"
206
+ f"**Final URL:** `{final_url}`\n"
207
+ f"**Status Code:** `{status_code}`")
208
+
209
+ await message.reply_document(document=f, caption=caption)
210
+ await msg.delete()
211
+ except Exception as e:
212
+ try: await msg.edit_text(f"❌ **Error fetching HTML:** `{str(e)}`")
213
+ except: pass
214
+
215
+
216
+ # --- STRING SESSION STATE MACHINE ---
217
+ input_waiters = {}
218
+
219
+ @app.on_message(filters.text & is_admin, group=-1)
220
+ async def catch_input(client, message):
221
+ chat_id = message.chat.id
222
+ if chat_id in input_waiters and not input_waiters[chat_id].done():
223
+ input_waiters[chat_id].set_result(message.text)
224
+ message.stop_propagation()
225
+
226
+ async def get_response(chat_id, timeout=300):
227
+ loop = asyncio.get_running_loop()
228
+ future = loop.create_future()
229
+ input_waiters[chat_id] = future
230
+ try: return await asyncio.wait_for(future, timeout)
231
+ finally: del input_waiters[chat_id]
232
+
233
+ @app.on_message(filters.command("getstring") & is_admin)
234
+ async def pyrogram_string_cmd(client, message):
235
+ chat_id = message.chat.id
236
+ try:
237
+ await message.reply_text("πŸ›  **Pyrogram Session Generator**\nEnter your `API_ID`:")
238
+ api_id = int((await get_response(chat_id)).strip())
239
+
240
+ await message.reply_text("Enter your `API_HASH`:")
241
+ api_hash = (await get_response(chat_id)).strip()
242
+
243
+ await message.reply_text("Enter the **Phone Number** (e.g., +1234567890):")
244
+ phone = (await get_response(chat_id)).replace(" ", "").strip()
245
+
246
+ await message.reply_text("⏳ Requesting OTP from Telegram...")
247
+
248
+ from pyrogram import Client as TmpClient
249
+ from pyrogram.errors import SessionPasswordNeeded
250
+
251
+ tmp_app = TmpClient("temp_session", api_id=api_id, api_hash=api_hash, in_memory=True)
252
+ await tmp_app.connect()
253
+
254
+ sent_code = await tmp_app.send_code(phone)
255
+
256
+ await message.reply_text("πŸ“₯ **Code Sent!**\n⚠️ Enter code with spaces (e.g., `1 2 3 4 5`):")
257
+ otp_code = (await get_response(chat_id)).replace(" ", "").strip()
258
+
259
+ try:
260
+ await tmp_app.sign_in(phone, sent_code.phone_code_hash, otp_code)
261
+ except SessionPasswordNeeded:
262
+ await message.reply_text("πŸ” **2FA Password Required:**")
263
+ pwd = (await get_response(chat_id)).strip()
264
+ await tmp_app.check_password(pwd)
265
+
266
+ string_session = await tmp_app.export_session_string()
267
+ await message.reply_text(f"βœ… **Session Generated!**\n\n`{string_session}`\n\n⚠️ Keep this secret.")
268
+ except asyncio.TimeoutError:
269
+ await message.reply_text("❌ **Timeout.** Run `/getstring` again.")
270
+ except Exception as e:
271
+ await message.reply_text(f"❌ **Error:** `{str(e)}`")
272
+ finally:
273
+ if 'tmp_app' in locals():
274
+ try: await tmp_app.disconnect()
275
+ except: pass
276
+
277
  # --- UI CALLBACKS ---
278
  @app.on_callback_query(is_admin)
279
  async def button_handler(client, query):
 
308
  log.info("Scanner Stopped")
309
  await query.edit_message_text("⏹ Scanner Stopped", reply_markup=get_dynamic_menu())
310
 
311
+ elif data == "set_min_length":
312
+ kb = InlineKeyboardMarkup([
313
+ [InlineKeyboardButton("4 Letters", callback_data="min_len_4"), InlineKeyboardButton("5 Letters", callback_data="min_len_5")],
314
+ [InlineKeyboardButton("6 Letters", callback_data="min_len_6"), InlineKeyboardButton("7 Letters", callback_data="min_len_7")],
315
+ [InlineKeyboardButton("Β« Back", callback_data="menu_settings")]
316
+ ])
317
+ await query.edit_message_text("πŸ“ **Select Minimum Word Length:**", reply_markup=kb)
318
+
319
+ elif data.startswith("min_len_"):
320
+ new_len = int(data.split("_")[2])
321
+ state.min_length = new_len
322
+ await query.edit_message_text(f"βœ… Filter updated to `{new_len}` letters.", reply_markup=get_settings_menu())
323
+
324
  elif data == "load_words":
325
  await query.edit_message_text("⏳ Processing and loading chunk into memory...")
326
  try:
 
343
  kb = InlineKeyboardMarkup([[InlineKeyboardButton("πŸ”„ Refresh", callback_data="refresh_status")], [InlineKeyboardButton("Β« Back", callback_data="back_main")]])
344
  try: await query.edit_message_text(msg, reply_markup=kb)
345
  except MessageNotModified: pass
346
+
347
+ elif data == "set_speed":
348
+ kb = InlineKeyboardMarkup([
349
+ [InlineKeyboardButton("10", callback_data="spd_10"), InlineKeyboardButton("20", callback_data="spd_20")],
350
+ [InlineKeyboardButton("30", callback_data="spd_30"), InlineKeyboardButton("50", callback_data="spd_50")],
351
+ [InlineKeyboardButton("Β« Back", callback_data="menu_settings")]
352
+ ])
353
+ await query.edit_message_text("⚑ **Select Concurrent Workers:**", reply_markup=kb)
354
+
355
+ elif data.startswith("spd_"):
356
+ state.concurrency = int(data.split("_")[1])
357
+ await query.edit_message_text("βœ… Speed Updated", reply_markup=get_settings_menu())
358
 
359
  elif data == "export_files":
360
  await query.edit_message_text("⏳ Preparing files from disk...")