2024-12-26 03:32:41 +03:00
using System.Security.Cryptography ;
using Microsoft.Extensions.Configuration ;
using Telegram.Bot ;
using Telegram.Bot.Types ;
using Telegram.Bot.Types.Enums ;
using UserOfTheDayBot.Data ;
using UserOfTheDayBot.Model ;
namespace UserOfTheDayBot.Services ;
public class BotService
{
private readonly ITelegramBotClient _botClient ;
private readonly IUserRepository _userRepository ;
private readonly IUserOfTheDayRepository _userOfTheDayRepository ;
public BotService ( IConfiguration configuration , IUserRepository userRepository , IUserOfTheDayRepository userOfTheDayRepository )
{
_botClient = new TelegramBotClient ( configuration [ "BotSettings:BotToken" ] ? ? Environment . GetEnvironmentVariable ( "BotSettings_BotToken" ) ) ;
_userRepository = userRepository ;
_userOfTheDayRepository = userOfTheDayRepository ;
}
public async Task HandleUpdateAsync ( Update update , CancellationToken cancellationToken )
{
if ( update . Type = = UpdateType . Message & & update . Message ? . Text ! = null )
{
var message = update . Message ;
if ( message . Text . StartsWith ( "/help" ) )
{
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Уйди. Попробуйте /reg" , cancellationToken : cancellationToken ) ;
}
else if ( message . Text . StartsWith ( "/reg" ) )
{
await RegisterUserAsync ( message , cancellationToken ) ;
}
else if ( message . Text . StartsWith ( "/useroftheday" ) )
{
await HandleUserOfTheDayCommandAsync ( message , UserOfTheDayType . UserOfTheDay , cancellationToken ) ;
}
else if ( message . Text . StartsWith ( "/loser" ) )
{
await HandleUserOfTheDayCommandAsync ( message , UserOfTheDayType . LoserOfTheDay , cancellationToken ) ;
}
else if ( message . Text . StartsWith ( "/stat" ) )
{
await HandleStatCommandAsync ( message , cancellationToken ) ;
}
else
{
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Неизвестная команда. Попробуйте /reg" , cancellationToken : cancellationToken ) ;
}
}
}
private async Task RegisterUserAsync ( Message message , CancellationToken cancellationToken )
{
try
{
int rowsAffected = await _userRepository . RegisterUserAsync ( message . Chat . Id , message . From . Id , message . From . FirstName ) ;
if ( rowsAffected > 0 )
{
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Вы успешно зарегистрированы!" , cancellationToken : cancellationToken ) ;
}
else
{
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Вы уже зарегистрированы." , cancellationToken : cancellationToken ) ;
}
}
catch ( Exception ex )
{
Console . WriteLine ( $"Error: {ex.Message}" ) ;
2024-12-26 03:35:11 +03:00
2024-12-26 03:32:41 +03:00
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Произошла ошибка при регистрации. Попробуйте позже." , cancellationToken : cancellationToken ) ;
}
}
private async Task HandleUserOfTheDayCommandAsync ( Message message , UserOfTheDayType type , CancellationToken cancellationToken )
{
try
{
var today = DateTime . UtcNow . Date ;
var chatId = message . Chat . Id ;
if ( await _userOfTheDayRepository . IsUserOfTheDaySelectedAsync ( chatId , today , type ) )
{
var responseMessage = type = = UserOfTheDayType . UserOfTheDay ? "Пользователь дня уже выбран." : "Неудачник дня уже выбран." ;
await _botClient . SendTextMessageAsync ( chatId , responseMessage , cancellationToken : cancellationToken ) ;
return ;
}
var selectedUser = await SelectUserOfTheDayAsync ( chatId , today , type ) ;
2024-12-26 04:48:14 +03:00
if ( selectedUser . userId is not null )
2024-12-26 03:32:41 +03:00
{
var responseMessage = type = = UserOfTheDayType . UserOfTheDay ? "Пользователь дня" : "Неудачник дня" ;
2024-12-26 04:48:14 +03:00
await _botClient . SendTextMessageAsync ( chatId , $"{responseMessage}: {selectedUser.userName}" , cancellationToken : cancellationToken ) ;
2024-12-26 03:32:41 +03:00
}
else
{
await _botClient . SendTextMessageAsync ( chatId , "В чате нет зарегистрированных пользователей." , cancellationToken : cancellationToken ) ;
}
}
catch ( Exception ex )
{
Console . WriteLine ( $"Error: {ex.Message}" ) ;
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Произошла ошибка при выборе пользователя дня. Попробуйте позже." , cancellationToken : cancellationToken ) ;
}
}
2024-12-26 04:48:14 +03:00
private async Task < ( long? userId , string userName ) > SelectUserOfTheDayAsync ( long chatId , DateTime date , UserOfTheDayType type )
2024-12-26 03:32:41 +03:00
{
var users = ( await _userRepository . GetUsersWithNamesAsync ( chatId ) ) . ToList ( ) ;
if ( users . Any ( ) )
{
using ( var rng = RandomNumberGenerator . Create ( ) )
{
while ( users . Count > 0 )
{
var randomIndex = GetRandomIndex ( users . Count , rng ) ;
var selectedUser = users [ randomIndex ] ;
if ( ! await _userOfTheDayRepository . IsUserAlreadySelectedAsync ( chatId , date , selectedUser . userId ) )
{
await _userOfTheDayRepository . RecordUserOfTheDayAsync ( chatId , selectedUser . userId , date , type ) ;
2024-12-26 04:48:14 +03:00
return ( selectedUser . userId , selectedUser . userName ) ;
2024-12-26 03:32:41 +03:00
}
users . RemoveAt ( randomIndex ) ;
}
}
}
2024-12-26 04:48:14 +03:00
return default ;
2024-12-26 03:32:41 +03:00
}
private async Task HandleStatCommandAsync ( Message message , CancellationToken cancellationToken )
{
try
{
var chatId = message . Chat . Id ;
var stats = await _userOfTheDayRepository . GetUserStatisticsAsync ( chatId ) ;
if ( stats . Any ( ) )
{
var userOfTheDaySection = "Пользователь дня:\n" ;
var loserOfTheDaySection = "Неудачник дня:\n" ;
var sortedUserOfTheDay = stats . OrderByDescending ( x = > x . Value . userOfTheDayCount ) ;
var sortedLoserOfTheDay = stats . OrderByDescending ( x = > x . Value . loserOfTheDayCount ) ;
foreach ( var stat in sortedUserOfTheDay )
{
userOfTheDaySection + = $"{stat.Key.userName}: {stat.Value.userOfTheDayCount} раз(а )\n" ;
}
foreach ( var stat in sortedLoserOfTheDay )
{
loserOfTheDaySection + = $"{stat.Key.userName}: {stat.Value.loserOfTheDayCount} раз(а )\n" ;
}
var response = userOfTheDaySection + "\n" + loserOfTheDaySection ;
await _botClient . SendTextMessageAsync ( chatId , response , cancellationToken : cancellationToken ) ;
}
else
{
await _botClient . SendTextMessageAsync ( chatId , "Нет данных о пользователях." , cancellationToken : cancellationToken ) ;
}
}
catch ( Exception ex )
{
Console . WriteLine ( $"Error: {ex.Message}" ) ;
await _botClient . SendTextMessageAsync ( message . Chat . Id , "Произошла ошибка при получении статистики. Попробуйте позже." , cancellationToken : cancellationToken ) ;
}
}
private static int GetRandomIndex ( int max , RandomNumberGenerator rng )
{
var buffer = new byte [ 4 ] ;
rng . GetBytes ( buffer ) ;
var randomValue = BitConverter . ToUInt32 ( buffer , 0 ) ;
return ( int ) ( randomValue % max ) ;
}
}