global update and global fix

This commit is contained in:
lendry
2026-06-25 23:48:57 +03:00
parent 3880c68d59
commit b0ea87e898
121 changed files with 13759 additions and 663 deletions

View File

@@ -0,0 +1,159 @@
import { Body, Controller, Delete, Get, Headers, Param, Patch, Post, Query } from '@nestjs/common';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiTags } from '@nestjs/swagger';
import { JwtService } from '@nestjs/jwt';
import { firstValueFrom } from 'rxjs';
import { CoreGrpcService } from '../core-grpc.service';
import { CreateBotDto, SetBotWebAppDto, SubmitBotCallbackDto, SubmitBotMessageDto, UpdateBotDto, UpdateBotProfileDto, ValidateWebAppInitDataDto } from '../dto/bot.dto';
import { getAuthorizedUserId } from '../document-access';
@ApiTags('BotFather')
@ApiBearerAuth()
@Controller('bots')
export class BotController {
constructor(
private readonly core: CoreGrpcService,
private readonly jwt: JwtService
) {}
private async auth(authorization?: string) {
return getAuthorizedUserId(this.jwt, this.core, authorization);
}
@Get()
@ApiOperation({ summary: 'Список моих ботов', description: 'Возвращает Telegram-ботов текущего пользователя.' })
listMyBots(@Headers('authorization') authorization?: string) {
return this.auth(authorization).then((userId) => firstValueFrom(this.core.bot.ListMyBots({ ownerId: userId })));
}
@Post()
@ApiOperation({ summary: 'Создать бота', description: 'Регистрирует нового бота и возвращает токен Bot API.' })
@ApiBody({ type: CreateBotDto })
createBot(@Headers('authorization') authorization: string | undefined, @Body() dto: CreateBotDto) {
return this.auth(authorization).then((ownerId) =>
firstValueFrom(this.core.bot.CreateBot({ ownerId, name: dto.name, username: dto.username }))
);
}
@Get('by-username/:botRef/messages')
@ApiOperation({ summary: 'История чата с ботом', description: 'Возвращает сообщения пользователя с ботом в хронологическом порядке.' })
listBotMessages(@Headers('authorization') authorization: string | undefined, @Param('botRef') botRef: string) {
return this.auth(authorization).then((userId) =>
firstValueFrom(this.core.bot.ListBotChatMessages({ userId, botRef }))
);
}
@Post('by-username/:botRef/messages')
@ApiOperation({
summary: 'Написать боту',
description: 'Публикует inbound-событие в RabbitMQ для доставки боту через webhook или getUpdates.'
})
@ApiBody({ type: SubmitBotMessageDto })
submitMessage(
@Headers('authorization') authorization: string | undefined,
@Param('botRef') botRef: string,
@Body() dto: SubmitBotMessageDto
) {
return this.auth(authorization).then((senderUserId) =>
firstValueFrom(this.core.bot.SubmitBotInboundMessage({ senderUserId, botRef, text: dto.text }))
);
}
@Post('by-username/:botRef/callback')
@ApiOperation({
summary: 'Нажатие inline-кнопки',
description: 'Публикует callback_query Update для webhook или getUpdates.'
})
@ApiBody({ type: SubmitBotCallbackDto })
submitCallback(
@Headers('authorization') authorization: string | undefined,
@Param('botRef') botRef: string,
@Body() dto: SubmitBotCallbackDto
) {
return this.auth(authorization).then((senderUserId) =>
firstValueFrom(
this.core.bot.SubmitBotCallbackQuery({
senderUserId,
botRef,
messageId: dto.messageId,
callbackData: dto.callbackData
})
)
);
}
@Post('web-app/validate')
@ApiOperation({
summary: 'Проверить initData Mini App',
description: 'Валидирует Telegram Web App initData по HMAC-SHA256, как в официальном Bot API.'
})
@ApiBody({ type: ValidateWebAppInitDataDto })
validateWebApp(@Body() dto: ValidateWebAppInitDataDto) {
return firstValueFrom(this.core.bot.ValidateWebAppInitData(dto));
}
@Get(':botId')
@ApiOperation({ summary: 'Получить бота', description: 'Возвращает настройки бота, принадлежащего пользователю.' })
getBot(@Headers('authorization') authorization: string | undefined, @Param('botId') botId: string) {
return this.auth(authorization).then((requesterId) =>
firstValueFrom(this.core.bot.GetBot({ requesterId, botId, isSuperAdmin: false }))
);
}
@Patch(':botId')
@ApiOperation({ summary: 'Обновить бота', description: 'Изменяет имя или username бота.' })
@ApiBody({ type: UpdateBotDto })
updateBot(
@Headers('authorization') authorization: string | undefined,
@Param('botId') botId: string,
@Body() dto: UpdateBotDto
) {
return this.auth(authorization).then((requesterId) =>
firstValueFrom(this.core.bot.UpdateBot({ requesterId, botId, ...dto, isSuperAdmin: false }))
);
}
@Delete(':botId')
@ApiOperation({ summary: 'Удалить бота', description: 'Удаляет бота и все связанные чаты/сообщения.' })
deleteBot(@Headers('authorization') authorization: string | undefined, @Param('botId') botId: string) {
return this.auth(authorization).then((requesterId) =>
firstValueFrom(this.core.bot.DeleteBot({ requesterId, botId, isSuperAdmin: false }))
);
}
@Post(':botId/revoke-token')
@ApiOperation({ summary: 'Перевыпустить токен', description: 'Инвалидирует старый токен и возвращает новый.' })
revokeToken(@Headers('authorization') authorization: string | undefined, @Param('botId') botId: string) {
return this.auth(authorization).then((requesterId) =>
firstValueFrom(this.core.bot.RevokeBotToken({ requesterId, botId, isSuperAdmin: false }))
);
}
@Patch(':botId/profile')
@ApiOperation({
summary: 'Профиль бота',
description: 'Обновляет description, aboutText, botPicUrl и глобальную кнопку меню (Web App).'
})
@ApiBody({ type: UpdateBotProfileDto })
updateBotProfile(
@Headers('authorization') authorization: string | undefined,
@Param('botId') botId: string,
@Body() dto: UpdateBotProfileDto
) {
return this.auth(authorization).then((requesterId) =>
firstValueFrom(this.core.bot.UpdateBotProfile({ requesterId, botId, ...dto, isSuperAdmin: false }))
);
}
@Patch(':botId/web-app')
@ApiOperation({ summary: 'Настроить Mini App', description: 'Привязывает URL Web App к боту.' })
@ApiBody({ type: SetBotWebAppDto })
setWebApp(
@Headers('authorization') authorization: string | undefined,
@Param('botId') botId: string,
@Body() dto: SetBotWebAppDto
) {
return this.auth(authorization).then((requesterId) =>
firstValueFrom(this.core.bot.SetBotWebApp({ requesterId, botId, webAppUrl: dto.webAppUrl, isSuperAdmin: false }))
);
}
}