#nullable enable using BotFramework; using BotFramework.Attributes; using BotFramework.Enums; using Kruzya.TelegramBot.Core.Extensions; using Kruzya.TelegramBot.Core.Service; using Microsoft.Extensions.DependencyInjection; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; using West.TelegramBot.ContentStore.Service; namespace West.TelegramBot.ContentStore.Handler; public class Store : BotEventHandler { private readonly IReputation? _reputation; private readonly IServiceProvider _provider; private readonly ContentStore _store; public Store(IServiceProvider provider, ContentStore store) { _reputation = provider.GetService(); _provider = provider; _store = store; } [Command(InChat.Public, "store", CommandParseMode.Both)] public async Task HandleStore() { if (From.IsBot) { return; } if (_reputation == null) { await Bot.SendTextMessageAsync(Chat.Id, "Reputation is unavailable."); return; } var user = From; var reputation = await _reputation.GetUserReputationAsync(Chat, user); await Bot.SendTextMessageAsync(Chat.Id, $"{user.ToHtml()} ({reputation}), чего пожелаете?", parseMode: ParseMode.Html, replyMarkup: new InlineKeyboardMarkup( _provider.GetServices() .ToAsyncEnumerable() .WhereAwait(async x => await x.CanView(Chat, user)) .OrderBy(x => x.StoreItem.Order) .Select(x => x.StoreItem.ToButton(From.Id)) .ToEnumerable() .Chunk(2) .ToList() ) ); } [Update(InChat.Public, UpdateFlag.CallbackQuery)] public async Task HandleStoreCallback() { var query = CallbackQuery; var queryData = query.Data; if (queryData == null || !queryData.StartsWith("store|") || _reputation == null) { return; } var paramList = queryData.Split('|'); if (!long.TryParse(paramList[1], out var senderId)) { return; } if (senderId != From.Id) { await AnswerQuery(query.Id, "Keyboard called by another user."); return; } var answer = "Unknown action."; if (paramList[2] == "purchase") { var purchaseType = paramList[3]; answer = "Спасибо за покупку"; if (!TryGetMediaService(purchaseType, out var mediaService)) { await AnswerQuery(query.Id, "Unknown purchasable."); return; } var storeItem = mediaService!.StoreItem; var messageId = query.Message!.MessageId; var reputation = await _reputation.GetUserReputationAsync(Chat, From); if (reputation < storeItem.Price) { await Bot.EditMessageTextAsync( Chat.Id, messageId, $"{From.ToHtml()} ({reputation}), продолжай работать и тебе обязательно хватит на покупку.", ParseMode.Html); await AnswerQuery(query.Id); return; } reputation = await _reputation.SetUserReputationAsync(Chat, From, reputation - storeItem.Price); await Bot.EditMessageTextAsync(Chat.Id, messageId, $"{From.ToHtml()} ({reputation}) купил \"{storeItem.Name}\".", ParseMode.Html); var randomMedia = await mediaService!.GetRandomMediaAsync(); var file = randomMedia.File; switch (randomMedia.Type) { case InputMediaType.Photo: await Bot.SendPhotoAsync(Chat.Id, file, caption: randomMedia.Caption, replyToMessageId: messageId, parseMode: ParseMode.Html, hasSpoiler: randomMedia.Nsfw ); break; case InputMediaType.Video: await Bot.SendVideoAsync(Chat.Id, file, caption: randomMedia.Caption, replyToMessageId: messageId, parseMode: ParseMode.Html, hasSpoiler: randomMedia.Nsfw ); break; } } await AnswerQuery(query.Id, answer); } private bool TryGetMediaService(string name, out IRandomMediaService? mediaService) { mediaService = _provider.GetServices() .FirstOrDefault(s => s.StoreItem.Id == name); return mediaService != null; } private async Task AnswerQuery(string id, string? message = null) { await Bot.AnswerCallbackQueryAsync(id, message); } }