Scope monitoring PF objects to Telegram-linked users

This commit is contained in:
Grendgi
2026-06-05 10:06:28 +03:00
parent 8bdac8b15b
commit ccfb261e7f
6 changed files with 213 additions and 79 deletions

View File

@@ -31,12 +31,20 @@ logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name
logger = logging.getLogger(__name__)
async def cmd_start(update: Update, _: ContextTypes.DEFAULT_TYPE) -> None:
def _portal_user_code(context: ContextTypes.DEFAULT_TYPE) -> str | None:
if not context.args:
return None
code = context.args[0].strip()
return code or None
async def cmd_start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.effective_user or not update.effective_chat:
return
user = update.effective_user
chat_id = str(update.effective_chat.id)
username = user.username
portal_user_id = _portal_user_code(context)
db = SessionLocal()
try:
@@ -44,6 +52,21 @@ async def cmd_start(update: Update, _: ContextTypes.DEFAULT_TYPE) -> None:
db.query(Employee).filter(Employee.tg_chat_id == chat_id).first()
)
if existing:
if portal_user_id and existing.portal_user_id and existing.portal_user_id != portal_user_id:
await update.message.reply_text(
"Этот Telegram уже подключен к другому пользователю Portal.",
)
return
if portal_user_id and not existing.portal_user_id:
clash = db.query(Employee).filter(Employee.portal_user_id == portal_user_id).first()
if clash and clash.id != existing.id:
await update.message.reply_text(
"Этот пользователь Portal уже подключен к другому Telegram.",
)
return
existing.portal_user_id = portal_user_id
existing.tg_username = username
db.commit()
await update.message.reply_text(
f"✅ Вы уже подключены как <b>{existing.name}</b>.\n"
f"chat_id: <code>{chat_id}</code>",
@@ -51,6 +74,34 @@ async def cmd_start(update: Update, _: ContextTypes.DEFAULT_TYPE) -> None:
)
return
if portal_user_id:
employee = db.query(Employee).filter(Employee.portal_user_id == portal_user_id).first()
name = (user.full_name or username or f"user_{chat_id}").strip()
if employee:
if employee.tg_chat_id and employee.tg_chat_id != chat_id:
await update.message.reply_text(
"Этот пользователь Portal уже подключен к другому Telegram.",
)
return
employee.name = employee.name or name
employee.tg_chat_id = chat_id
employee.tg_username = username
else:
employee = Employee(
name=name,
portal_user_id=portal_user_id,
tg_chat_id=chat_id,
tg_username=username,
)
db.add(employee)
db.commit()
await update.message.reply_text(
f"✅ Привет, <b>{name}</b>! Telegram подключен к вашему аккаунту Portal.\n"
f"Теперь можно добавлять объекты мониторинга в Portal.",
parse_mode="HTML",
)
return
# Try to find by username (admin pre-created employee w/o chat_id)
if username:
placeholder = (
@@ -68,15 +119,10 @@ async def cmd_start(update: Update, _: ContextTypes.DEFAULT_TYPE) -> None:
)
return
# Create a new employee record from this user
name = (user.full_name or username or f"user_{chat_id}").strip()
e = Employee(name=name, tg_chat_id=chat_id, tg_username=username)
db.add(e)
db.commit()
await update.message.reply_text(
f"👋 Привет, <b>{name}</b>! Вы зарегистрированы как сотрудник.\n"
f"Откройте веб-интерфейс и создайте проекты, чтобы получать уведомления.\n"
f"chat_id: <code>{chat_id}</code>",
"Откройте Portal → Мониторинг PF и нажмите подключение Telegram.\n"
"Бот должен получить команду вида:\n"
"<code>/start ваш_код_из_Portal</code>",
parse_mode="HTML",
)
finally: