Skip to content

Commit bb0a710

Browse files
Update main.py
1 parent 8a9b612 commit bb0a710

1 file changed

Lines changed: 83 additions & 15 deletions

File tree

main.py

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
import re
2-
import json
3-
import asyncio
4-
import logging
5-
import os
6-
from pathlib import Path
7-
from aiogram import Bot, Dispatcher, F
8-
from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
9-
from aiogram.enums import ParseMode
10-
from aiogram.filters import Command
11-
from aiogram.client.default import DefaultBotProperties
12-
from dotenv import load_dotenv
13-
from keep_alive import keep_alive
1+
import re import json import asyncio import logging import os from pathlib import Path from aiogram import Bot, Dispatcher, F from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton from aiogram.enums import ParseMode from aiogram.filters import Command from aiogram.client.default import DefaultBotProperties from dotenv import load_dotenv from keep_alive import keep_alive
142

153
Load environment variables
164

@@ -50,11 +38,13 @@ def is_admin(user_id: int) -> bool: return int(user_id) in ADMIN_IDS
5038

5139
=== COMMAND HANDLERS ===
5240

53-
@dp.message(Command("start")) async def cmd_start(msg: Message): try: me = await bot.get_me() status = f"\n🤖 <b>{me.first_name}</b> is online.\nUsername: @{me.username}\nID: <code>{me.id}</code>\n" except Exception as e: logger.error(f"Status check failed: {e}") status = "⚠️ Bot is online, but couldn't fetch status."
41+
@dp.message(Command("start")) async def cmd_start(msg: Message): try: me = await bot.get_me() status = f"\n🤖 <b>{me.first_name}</b> is online.\nUsername: @{me.username}\nID: <code>{me.id}</code>" except Exception as e: logger.error(f"Status check failed: {e}") status = "\n⚠️ Bot is online, but couldn't fetch status."
5442

5543
welcome_text = f"""
5644
57-
{status} <b>Admin Commands:</b> /addurl [Label] [URL] — Add one referral link
45+
{status}
46+
47+
<b>Admin Commands:</b> /addurl [Label] [URL] — Add one referral link
5848
/addurls — Add multiple links (one per line)
5949
/delurl [URL] — Remove a referral link
6050
/delurls — Remove multiple referral links
@@ -154,4 +144,82 @@ def is_admin(user_id: int) -> bool: return int(user_id) in ADMIN_IDS
154144
not_found.append(escape_html(url))
155145

156146
if removed:
147+
save_links(links_db)
148+
149+
reply = ""
150+
if removed:
151+
reply += "❌ Removed:\n" + "\n".join(removed)
152+
if not_found:
153+
reply += "\n\n⚠️ Not found:\n" + "\n".join(not_found)
154+
155+
await msg.reply(reply or "No URLs to remove.")
156+
except Exception as e:
157+
logger.error(f"delurls error: {e}")
158+
await msg.reply("❌ Error deleting URLs.")
159+
160+
@dp.message(Command("listurls")) async def cmd_listurls(msg: Message): if not is_admin(msg.from_user.id): await msg.reply("❌ Only admins can use this command.") return
161+
162+
try:
163+
if not links_db:
164+
await msg.reply("No links saved.")
165+
return
166+
167+
lines = [f"{i}. {escape_html(v['label'])}{escape_html(k)}" for i, (k, v) in enumerate(links_db.items(), 1)]
168+
text = f"<b>Saved Links ({len(links_db)}):</b>\n\n" + "\n".join(lines)
169+
170+
for i in range(0, len(text), 4000):
171+
await msg.reply(text[i:i + 4000])
172+
except Exception as e:
173+
logger.error(f"listurls error: {e}")
174+
await msg.reply("❌ Error listing links.")
175+
176+
@dp.message(Command("setbutton")) async def cmd_setbutton(msg: Message): if not is_admin(msg.from_user.id): await msg.reply("❌ Only admins can use this command.") return
177+
178+
try:
179+
parts = msg.text.split(maxsplit=2)
180+
if len(parts) < 3:
181+
await msg.reply("Usage: /setbutton [URL] [Text]")
182+
return
183+
184+
url, label = parts[1], parts[2]
185+
if url not in links_db:
186+
await msg.reply("URL not found.")
187+
return
188+
189+
links_db[url]["label"] = label
190+
save_links(links_db)
191+
await msg.reply(f"🔁 Updated label for {escape_html(url)} to: <b>{escape_html(label)}</b>")
192+
except Exception as e:
193+
logger.error(f"setbutton error: {e}")
194+
await msg.reply("❌ Error updating label.")
195+
196+
=== AUTO FORMAT ===
197+
198+
@dp.message() async def auto_edit(msg: Message): try: text = msg.text or "" if not text or not links_db: return
199+
200+
found_urls = [url for url in links_db if url in text]
201+
if not found_urls:
202+
return
203+
204+
code_match = re.search(r'(code[:\s]*)([A-Za-z0-9@_-]+)', text, re.IGNORECASE)
205+
code_text = f"<b>Code:</b> {escape_html(code_match.group(2))}\n\n" if code_match else ""
206+
title = text.splitlines()[0] if text.splitlines() else "Referral Links"
207+
new_text = f"<b>{escape_html(title)}</b>\n\n{code_text}<b>Links below:</b>"
208+
209+
keyboard = build_keyboard(found_urls)
210+
await bot.edit_message_text(chat_id=msg.chat.id, message_id=msg.message_id, text=new_text, reply_markup=keyboard)
211+
except Exception as e:
212+
logger.warning(f"Auto-format failed: {e}")
213+
214+
=== LIFECYCLE ===
215+
216+
async def on_startup(): logger.info("Bot is starting...") try: await bot.delete_webhook(drop_pending_updates=True) logger.info("Webhook deleted.") except Exception as e: logger.warning(f"Webhook delete failed: {e}")
217+
218+
async def on_shutdown(): logger.info("Bot shutting down...") await bot.session.close()
219+
220+
=== MAIN LOOP ===
221+
222+
async def main(): retry = 0 while retry < 5: try: await on_startup() await dp.start_polling(bot, skip_updates=True) except KeyboardInterrupt: break except Exception as e: retry += 1 logger.error(f"Crash: {e}, retrying in {2 ** retry}s...") await asyncio.sleep(min(60, 2 ** retry)) finally: await on_shutdown()
223+
224+
if name == "main": keep_alive() try: asyncio.run(main()) except Exception as e: logger.error(f"Fatal: {e}")
157225

0 commit comments

Comments
 (0)