Добавление админа по ссылке VK (не только числовой ID)
Бот принимает ссылку (https://vk.com/gruzdevas), короткое имя (gruzdevas), @имя или числовой ID и сам определяет user_id (короткое имя — через VK API users.get). Резолвер _resolve_vk_user_id применён к добавлению и удалению админа. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -207,6 +207,32 @@ class VKBotApplication:
|
|||||||
logger.error(f"Не удалось получить имя VK для {user_id}: {e}")
|
logger.error(f"Не удалось получить имя VK для {user_id}: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _resolve_vk_user_id(self, raw: str) -> Optional[int]:
|
||||||
|
"""Из ссылки / короткого имени / ID получает числовой VK user_id (или None).
|
||||||
|
|
||||||
|
Принимает что угодно: https://vk.com/gruzdevas, vk.com/id123, @gruzdevas,
|
||||||
|
gruzdevas, 123456. Короткое имя резолвится через VK API.
|
||||||
|
"""
|
||||||
|
s = (raw or "").strip()
|
||||||
|
s = re.sub(r"^https?://", "", s, flags=re.I) # убираем протокол
|
||||||
|
s = re.sub(r"^(m\.)?vk\.com/", "", s, flags=re.I) # убираем домен
|
||||||
|
s = s.split("?")[0].split("/")[0].strip().strip("@").strip() # берём первый сегмент
|
||||||
|
if not s:
|
||||||
|
return None
|
||||||
|
m = re.match(r"^id(\d+)$", s, flags=re.I) # id123456
|
||||||
|
if m:
|
||||||
|
return int(m.group(1))
|
||||||
|
if s.isdigit(): # чистое число
|
||||||
|
return int(s)
|
||||||
|
if self.vk: # короткое имя → через API
|
||||||
|
try:
|
||||||
|
info = self.vk.users.get(user_ids=s)
|
||||||
|
if info:
|
||||||
|
return int(info[0]["id"])
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Не удалось определить VK id по '{s}': {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _progress_bar(step: int, total: int = 3) -> str:
|
def _progress_bar(step: int, total: int = 3) -> str:
|
||||||
"""Визуальный прогресс шага формы: ▰▰▱ Шаг 2 из 3."""
|
"""Визуальный прогресс шага формы: ▰▰▱ Шаг 2 из 3."""
|
||||||
@@ -267,11 +293,18 @@ class VKBotApplication:
|
|||||||
if not self._is_super_admin(user_id):
|
if not self._is_super_admin(user_id):
|
||||||
self.send_message(user_id, "⛔ Добавлять админов может только супер-админ.")
|
self.send_message(user_id, "⛔ Добавлять админов может только супер-админ.")
|
||||||
return
|
return
|
||||||
arg = text.split(" ", 2)[-1].strip()
|
raw = text
|
||||||
if not arg.lstrip("-").isdigit():
|
if text.lower().startswith("админ доб"):
|
||||||
self.send_message(user_id, "⚠️ Формат: админ доб [VK_ID числом]")
|
raw = text[len("админ доб"):].strip()
|
||||||
|
new_id = self._resolve_vk_user_id(raw)
|
||||||
|
if not new_id:
|
||||||
|
self.send_message(
|
||||||
|
user_id,
|
||||||
|
"⚠️ Не смог определить пользователя.\n"
|
||||||
|
"Пришлите ссылку на страницу VK (например, https://vk.com/gruzdevas), "
|
||||||
|
"короткое имя (gruzdevas) или числовой ID."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
new_id = int(arg)
|
|
||||||
if db.add_admin(new_id):
|
if db.add_admin(new_id):
|
||||||
self._admins_cache = None # инвалидируем кэш админов
|
self._admins_cache = None # инвалидируем кэш админов
|
||||||
self.send_message(user_id, f"✅ Пользователь vk.com/id{new_id} теперь администратор.")
|
self.send_message(user_id, f"✅ Пользователь vk.com/id{new_id} теперь администратор.")
|
||||||
@@ -288,11 +321,13 @@ class VKBotApplication:
|
|||||||
if not self._is_super_admin(user_id):
|
if not self._is_super_admin(user_id):
|
||||||
self.send_message(user_id, "⛔ Удалять админов может только супер-админ.")
|
self.send_message(user_id, "⛔ Удалять админов может только супер-админ.")
|
||||||
return
|
return
|
||||||
arg = text.split(" ", 2)[-1].strip()
|
raw = text
|
||||||
if not arg.lstrip("-").isdigit():
|
if text.lower().startswith("админ удал"):
|
||||||
self.send_message(user_id, "⚠️ Формат: админ удал [VK_ID числом]")
|
raw = text[len("админ удал"):].strip()
|
||||||
|
rem_id = self._resolve_vk_user_id(raw)
|
||||||
|
if not rem_id:
|
||||||
|
self.send_message(user_id, "⚠️ Не смог определить пользователя. Пришлите ссылку/имя/ID.")
|
||||||
return
|
return
|
||||||
rem_id = int(arg)
|
|
||||||
if db.remove_admin(rem_id):
|
if db.remove_admin(rem_id):
|
||||||
self._admins_cache = None # инвалидируем кэш админов
|
self._admins_cache = None # инвалидируем кэш админов
|
||||||
self.send_message(user_id, f"✅ Пользователь vk.com/id{rem_id} больше не администратор.")
|
self.send_message(user_id, f"✅ Пользователь vk.com/id{rem_id} больше не администратор.")
|
||||||
@@ -489,8 +524,9 @@ class VKBotApplication:
|
|||||||
self.send_message(user_id, "⛔ Только супер-админ.")
|
self.send_message(user_id, "⛔ Только супер-админ.")
|
||||||
return
|
return
|
||||||
db.update_user_state(user_id, "ADMIN_ADMIN_ADD")
|
db.update_user_state(user_id, "ADMIN_ADMIN_ADD")
|
||||||
self.send_message(user_id, "➕ Пришлите VK ID нового администратора (числом).\n"
|
self.send_message(user_id, "➕ Пришлите ссылку на страницу нового администратора в VK\n"
|
||||||
"ID можно узнать на vk.com/<id> или через сервисы определения id.",
|
"(например, https://vk.com/gruzdevas). Можно также короткое имя "
|
||||||
|
"или числовой ID — бот сам разберётся.",
|
||||||
keyboard=get_cancel_admin_keyboard())
|
keyboard=get_cancel_admin_keyboard())
|
||||||
return
|
return
|
||||||
elif text_lower in ["🗑 удалить админа", "удалить админа"]:
|
elif text_lower in ["🗑 удалить админа", "удалить админа"]:
|
||||||
@@ -2099,7 +2135,7 @@ class VKBotApplication:
|
|||||||
db.update_user_state(user_id, "FREE_CHAT")
|
db.update_user_state(user_id, "FREE_CHAT")
|
||||||
self._send_admin_panel(user_id)
|
self._send_admin_panel(user_id)
|
||||||
return
|
return
|
||||||
self._handle_admin_add_admin(user_id, "админ доб " + pick_id(text))
|
self._handle_admin_add_admin(user_id, text) # передаём сырой текст (ссылка/имя/ID)
|
||||||
db.update_user_state(user_id, "FREE_CHAT")
|
db.update_user_state(user_id, "FREE_CHAT")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user