2022-02-16 17:07:30 +02:00
|
|
|
#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.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;
|
2022-02-16 18:08:02 +02:00
|
|
|
private readonly ContentStore _store;
|
|
|
|
|
|
|
|
|
|
public Store(IServiceProvider provider, ContentStore store)
|
2022-02-16 17:07:30 +02:00
|
|
|
{
|
|
|
|
|
_reputation = provider.GetService<IReputation>();
|
|
|
|
|
_provider = provider;
|
2022-02-16 18:08:02 +02:00
|
|
|
_store = store;
|
2022-02-16 17:07:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Command(InChat.Public, "store", CommandParseMode.Both)]
|
|
|
|
|
public async Task HandleStore()
|
|
|
|
|
{
|
2022-05-10 19:11:01 +03:00
|
|
|
if (From.IsBot)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-16 17:07:30 +02:00
|
|
|
if (_reputation == null)
|
|
|
|
|
{
|
|
|
|
|
await Bot.SendTextMessageAsync(Chat.Id, "Reputation is unavailable.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-04-26 00:28:39 +03:00
|
|
|
|
|
|
|
|
var user = From;
|
|
|
|
|
var reputation = await _reputation.GetUserReputationAsync(Chat, user);
|
2022-02-25 20:47:24 +02:00
|
|
|
|
2023-01-02 19:01:03 +02:00
|
|
|
await Bot.SendTextMessageAsync(Chat.Id, $"<b>{user.ToHtml()} ({reputation})</b>, чего пожелаете?", parseMode: ParseMode.Html,
|
2022-04-26 00:28:39 +03:00
|
|
|
replyMarkup: new InlineKeyboardMarkup(
|
|
|
|
|
_provider.GetServices<IRandomMediaService>()
|
2022-11-14 00:23:36 +02:00
|
|
|
.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()
|
|
|
|
|
)
|
2022-02-25 20:47:24 +02:00
|
|
|
);
|
2022-02-16 17:07:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[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 = "Спасибо за покупку";
|
|
|
|
|
|
2022-02-16 18:08:02 +02:00
|
|
|
if (!TryGetMediaService(purchaseType, out var mediaService))
|
2022-02-16 17:07:30 +02:00
|
|
|
{
|
|
|
|
|
await AnswerQuery(query.Id, "Unknown purchasable.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 19:11:01 +03:00
|
|
|
var storeItem = mediaService!.StoreItem;
|
2022-02-16 17:07:30 +02:00
|
|
|
var messageId = query.Message!.MessageId;
|
2022-04-26 00:49:32 +03:00
|
|
|
var reputation = await _reputation.GetUserReputationAsync(Chat, From);
|
|
|
|
|
if (reputation < storeItem.Price)
|
2022-02-16 17:07:30 +02:00
|
|
|
{
|
|
|
|
|
await Bot.EditMessageTextAsync(
|
|
|
|
|
Chat.Id,
|
|
|
|
|
messageId,
|
2022-04-26 00:49:32 +03:00
|
|
|
$"<b>{From.ToHtml()} ({reputation})</b>, продолжай работать и тебе обязательно хватит на покупку.",
|
2022-02-16 17:07:30 +02:00
|
|
|
ParseMode.Html);
|
|
|
|
|
await AnswerQuery(query.Id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-26 00:49:32 +03:00
|
|
|
reputation = await _reputation.SetUserReputationAsync(Chat, From, reputation - storeItem.Price);
|
2022-02-16 17:11:29 +02:00
|
|
|
await Bot.EditMessageTextAsync(Chat.Id,
|
|
|
|
|
messageId,
|
2022-04-26 00:49:32 +03:00
|
|
|
$"<b>{From.ToHtml()} ({reputation})</b> купил \"{storeItem.Name}\".",
|
2022-02-16 17:11:29 +02:00
|
|
|
ParseMode.Html);
|
2022-02-16 17:07:30 +02:00
|
|
|
|
|
|
|
|
var randomMedia = await mediaService!.GetRandomMediaAsync();
|
2022-11-14 00:23:36 +02:00
|
|
|
var file = randomMedia.File;
|
2022-02-16 17:07:30 +02:00
|
|
|
switch (randomMedia.Type)
|
|
|
|
|
{
|
|
|
|
|
case InputMediaType.Photo:
|
2023-01-02 19:01:03 +02:00
|
|
|
await Bot.SendPhotoAsync(Chat.Id, file, 0, randomMedia.Caption, replyToMessageId: messageId, parseMode: ParseMode.Html);
|
2022-02-16 17:07:30 +02:00
|
|
|
break;
|
|
|
|
|
case InputMediaType.Video:
|
2022-11-14 00:23:36 +02:00
|
|
|
await Bot.SendVideoAsync(Chat.Id, file, caption: randomMedia.Caption, replyToMessageId: messageId, parseMode: ParseMode.Html);
|
2022-02-16 17:07:30 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await AnswerQuery(query.Id, answer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool TryGetMediaService(string name, out IRandomMediaService? mediaService)
|
|
|
|
|
{
|
2022-02-16 18:08:02 +02:00
|
|
|
mediaService = _provider.GetServices<IRandomMediaService>()
|
|
|
|
|
.FirstOrDefault(s => s.StoreItem.Id == name);
|
|
|
|
|
|
2022-02-16 17:07:30 +02:00
|
|
|
return mediaService != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task AnswerQuery(string id, string? message = null)
|
|
|
|
|
{
|
|
|
|
|
await Bot.AnswerCallbackQueryAsync(id, message);
|
|
|
|
|
}
|
|
|
|
|
}
|