#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BotFramework.Abstractions; using Kruzya.TelegramBot.Core.Cache; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Telegram.Bot; using Telegram.Bot.Types; namespace Kruzya.TelegramBot.Core.Service; public class UserService { private readonly IEnumerable _superUsers; private readonly IEnumerable _badLuckUsers; private readonly Dictionary _statusMap; private readonly ICacheStorage _userCache; private readonly ITelegramBotClient _bot; private readonly ILogger _logger; public UserService( IConfiguration configuration, IBotInstance bot, ICacheStorage userCache, ILogger logger) { _superUsers = configuration.GetSection("SuperUsers").Get>() ?? new List(); _badLuckUsers = configuration.GetSection("BadLuckUsers").Get>() ?? new List(); _statusMap = configuration.GetSection("CustomMemberStatus") .GetChildren() .ToDictionary(x => Convert.ToInt64(x.Key), x => x.Value); _userCache = userCache; _bot = bot.BotClient; _logger = logger; } public async Task GetUser(long userId, long chatId, bool bypassCache = false) { if (bypassCache || !_userCache.TryGetValue(userId, out var user)) { if (bypassCache) { _logger.LogDebug("Bypassing cache for {UserId}.", userId); } else { _logger.LogDebug("User {UserId} is not found in cache. Fetching from Telegram API.", userId); } user = await GetUserByChat(chatId, userId); CacheUser(user); } return user; } private void CacheUser(User user) { // TODO: config entry for TTL _userCache.SetValue(user.Id, user, Convert.ToInt32(TimeSpan.FromHours(1).TotalSeconds)); } private async Task GetUserByChat(long chatId, long userId) { return (await _bot.GetChatMember(chatId, userId)).User; } public bool IsUserSuper(User user) { return IsUserSuper(user.Id); } public bool IsUserSuper(long userId) { return _superUsers.Contains(userId); } public bool IsUserUnlucky(long userId) { return _badLuckUsers.Contains(userId); } public string? GetUserCustomStatus(long userId) { return _statusMap.ContainsKey(userId) ? _statusMap[userId] : null; } }