Files
tgex-backend/src/usecase/project/tg_add_project_1.py

158 lines
6.2 KiB
Python

import logging
from typing import TYPE_CHECKING
from aiogram.types import InlineKeyboardButton
from src import domain, dto
if TYPE_CHECKING:
from .. import Usecase
log = logging.getLogger(__name__)
async def tg_add_project_1(self: 'Usecase', input: dto.ConnectProjectInput) -> dto.ProjectOutput | None:
permissions = input.bot_permissions
if not permissions.is_admin:
log.warning(f'Bot is not admin in channel {input.telegram_id}. Attempted by user {input.user_telegram_id}')
await self.telegram_bot.send_message(
f'⚠️ Бот был добавлен в канал "{input.title}", но не является админом.\n\n'
'Пожалуйста, сделайте бота администратором канала.',
input.user_telegram_id,
)
raise domain.ChannelNoAdminRights()
missing_permissions = []
if not permissions.can_invite_users:
missing_permissions.append('Создание инвайт-ссылок')
if not permissions.can_restrict_members:
missing_permissions.append('Управление пользователями (видеть вступления)')
if missing_permissions:
log.warning(
f'Bot lacks required permissions in channel {input.telegram_id}: {missing_permissions}. '
f'Attempted by user {input.user_telegram_id}'
)
permissions_text = '\n'.join(f'{p}' for p in missing_permissions)
await self.telegram_bot.send_message(
f'⚠️ Бот был добавлен в канал "{input.title}", но не имеет необходимых прав.\n\n'
f'Отсутствующие права:\n{permissions_text}\n\n'
'Пожалуйста, предоставьте эти права боту в настройках канала.',
input.user_telegram_id,
)
raise domain.ChannelNoAdminRights()
user = await self.database.get_user(telegram_id=input.user_telegram_id)
if not user:
log.warning(f'User {input.user_telegram_id} not found when trying to connect channel {input.telegram_id}')
await self.telegram_bot.send_message(
f'⚠️ Канал "{input.title}" не может быть подключен.\n\n'
'Вы должны сначала авторизоваться в веб-панели перед подключением каналов.',
input.user_telegram_id,
)
raise domain.UserNotFound()
memberships = await self.database.get_user_workspaces(user.id)
workspaces: list[domain.Workspace] = []
for membership in memberships:
workspace: domain.Workspace | None = membership.workspace
if not workspace:
workspace = await self.database.get_workspace(membership.workspace_id)
if workspace:
workspaces.append(workspace)
if not workspaces:
workspace = await self.get_or_create_personal_workspace(user)
workspaces = [workspace]
if len(workspaces) == 1:
workspace = workspaces[0]
channel = await self.database.get_channel(workspace.id, telegram_id=input.telegram_id)
if channel:
channel.title = input.title
channel.username = input.username
await self.database.update_channel(channel)
else:
channel = domain.Channel(
telegram_id=input.telegram_id,
title=input.title,
username=input.username,
workspace_id=workspace.id,
)
await self.database.create_channel(channel)
project = await self.database.get_project(workspace.id, channel_id=channel.id)
if project:
project.status = domain.ProjectStatus.ACTIVE
await self.database.update_project(project)
else:
project = domain.Project(
workspace_id=workspace.id,
channel_id=channel.id,
status=domain.ProjectStatus.ACTIVE,
)
await self.database.create_project(project)
await self.ensure_active_purchase_plan(project)
log.info(
'Project for channel %s connected/updated successfully in workspace %s by user %s',
input.telegram_id,
workspace.id,
input.user_telegram_id,
)
await self.telegram_bot.send_message(
f'✅ Канал "{input.title}" добавлен в рабочее пространство "{workspace.name}".', input.user_telegram_id
)
return dto.ProjectOutput(
id=project.id,
telegram_id=channel.telegram_id,
title=channel.title,
username=channel.username,
status=project.status,
)
current_state = await self.database.get_telegram_state(user.telegram_id)
if current_state and current_state.state == domain.TelegramStateEnum.PROJECT_WAITING_WORKSPACE:
await self.telegram_bot.send_message(
'⚠️ Сначала завершите выбор рабочего пространства для предыдущего канала.', user.telegram_id
)
return None
context: dict[str, object] = {
'channel_data': {
'telegram_id': input.telegram_id,
'title': input.title,
'username': input.username,
'permissions': input.bot_permissions.model_dump(),
}
}
if current_state:
context['previous_state'] = current_state.state.value
context['previous_context'] = dict(current_state.context or {})
await self.database.set_telegram_state(
user.telegram_id,
domain.TelegramStateEnum.PROJECT_WAITING_WORKSPACE,
context,
)
buttons = [
[InlineKeyboardButton(text=workspace.name, callback_data=f'tg_add_project_2:{workspace.id}')]
for workspace in workspaces
]
await self.telegram_bot.send_message_with_inline_keyboard(
(f'✨ Подключение канала\n\nВыберите рабочее пространство, в которое добавить канал "{input.title}":'),
user.telegram_id,
buttons,
)
return None