TgBots/Services/BotService.cs
Dmitrii Prokudin ac708b5e69
All checks were successful
Local Deploy with Docker / build-and-deploy (push) Successful in 4s
Rebuild
2024-12-26 03:35:11 +03:00

189 lines
8.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}");
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);
if (selectedUser.HasValue)
{
var responseMessage = type == UserOfTheDayType.UserOfTheDay ? "Пользователь дня" : "Неудачник дня";
await _botClient.SendTextMessageAsync(chatId, $"{responseMessage}: {selectedUser.Value}", 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 async Task<long?> SelectUserOfTheDayAsync(long chatId, DateTime date, UserOfTheDayType type)
{
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);
return selectedUser.userId;
}
users.RemoveAt(randomIndex);
}
}
}
return null;
}
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);
}
}