mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
Merge pull request #8 from CrazyHackGUT/feature/content-store
Content store
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Core' " />
|
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Core' " />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AleXr64.BotFramework" Version="0.6.8-g0882b76d16" />
|
<PackageReference Include="AleXr64.BotFramework" Version="0.6.9-gf1e77653ff" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.1">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ COPY ./modules/Entertainment/*.csproj ./modules/Entertainment/
|
|||||||
COPY ./modules/UserGroupTag/*.csproj ./modules/UserGroupTag/
|
COPY ./modules/UserGroupTag/*.csproj ./modules/UserGroupTag/
|
||||||
COPY ./modules/ChatQuotes/*.csproj ./modules/ChatQuotes/
|
COPY ./modules/ChatQuotes/*.csproj ./modules/ChatQuotes/
|
||||||
COPY ./modules/Reputation/*.csproj ./modules/Reputation/
|
COPY ./modules/Reputation/*.csproj ./modules/Reputation/
|
||||||
|
COPY ./modules/ContentStore/*.csproj ./modules/ContentStore/
|
||||||
RUN dotnet restore Kruzya.TelegramBot.sln
|
RUN dotnet restore Kruzya.TelegramBot.sln
|
||||||
|
|
||||||
# Copy all project files
|
# Copy all project files
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Entertainment", "modules\En
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatQuotes", "modules\ChatQuotes\ChatQuotes.csproj", "{04F16325-8F44-4250-9B2E-0F77E8F65CBF}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatQuotes", "modules\ChatQuotes\ChatQuotes.csproj", "{04F16325-8F44-4250-9B2E-0F77E8F65CBF}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reputation", "modules\Reputation\Reputation.csproj", "{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reputation", "modules\Reputation\Reputation.csproj", "{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContentStore", "modules\ContentStore\ContentStore.csproj", "{4F1E8FE8-640F-4671-87FC-0FFCCB6EDF5E}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -77,6 +79,10 @@ Global
|
|||||||
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4F1E8FE8-640F-4671-87FC-0FFCCB6EDF5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4F1E8FE8-640F-4671-87FC-0FFCCB6EDF5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4F1E8FE8-640F-4671-87FC-0FFCCB6EDF5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4F1E8FE8-640F-4671-87FC-0FFCCB6EDF5E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -91,6 +97,7 @@ Global
|
|||||||
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
{04F16325-8F44-4250-9B2E-0F77E8F65CBF} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
{04F16325-8F44-4250-9B2E-0F77E8F65CBF} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
{03F3C7D5-6FEF-4A83-9191-501091BFC1AC} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
|
{4F1E8FE8-640F-4671-87FC-0FFCCB6EDF5E} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {5BA73C3B-D5FC-4942-9091-504325CDC308}
|
SolutionGuid = {5BA73C3B-D5FC-4942-9091-504325CDC308}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Kruzya.TelegramBot.Core;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using West.TelegramBot.ContentStore.Service;
|
||||||
|
using Module = Kruzya.TelegramBot.Core.Module;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore;
|
||||||
|
|
||||||
|
public class ContentStore : Module
|
||||||
|
{
|
||||||
|
public readonly List<Type> MediaServiceTypes = new();
|
||||||
|
|
||||||
|
public ContentStore(Core core) : base(core)
|
||||||
|
{
|
||||||
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
{
|
||||||
|
foreach (var exportedType in assembly.GetExportedTypes()
|
||||||
|
.Where(t => !t.IsAbstract && t.GetInterface(nameof(IRandomMediaService)) != null))
|
||||||
|
{
|
||||||
|
MediaServiceTypes.Add(exportedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
foreach (var serviceType in MediaServiceTypes)
|
||||||
|
{
|
||||||
|
services.AddSingleton(typeof(IRandomMediaService), serviceType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<AssemblyName>TelegramBot.ContentStore</AssemblyName>
|
||||||
|
<RootNamespace>West.TelegramBot.ContentStore</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Core\Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Handler\" />
|
||||||
|
<Folder Include="Model\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
#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.InputFiles;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
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<IReputation>();
|
||||||
|
_provider = provider;
|
||||||
|
_store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(InChat.Public, "store", CommandParseMode.Both)]
|
||||||
|
public async Task HandleStore()
|
||||||
|
{
|
||||||
|
if (_reputation == null)
|
||||||
|
{
|
||||||
|
await Bot.SendTextMessageAsync(Chat.Id, "Reputation is unavailable.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rowList = new List<List<InlineKeyboardButton>>();
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
var list = new List<InlineKeyboardButton>();
|
||||||
|
foreach (var item in _provider.GetServices<IRandomMediaService>())
|
||||||
|
{
|
||||||
|
var btn = item.StoreItem.ToButton(From.Id);
|
||||||
|
if ((counter & 1) == 0) // 0 - even, 1 - odd
|
||||||
|
{
|
||||||
|
list = new List<InlineKeyboardButton>
|
||||||
|
{
|
||||||
|
btn
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list.Add(btn);
|
||||||
|
rowList.Add(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Bot.SendTextMessageAsync(Chat.Id, "Чего пожелаете?", replyMarkup: new InlineKeyboardMarkup(rowList));
|
||||||
|
}
|
||||||
|
|
||||||
|
[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;
|
||||||
|
if (await _reputation.GetUserReputationAsync(Chat, From) < storeItem.Price)
|
||||||
|
{
|
||||||
|
await Bot.EditMessageTextAsync(
|
||||||
|
Chat.Id,
|
||||||
|
messageId,
|
||||||
|
$"{From.ToHtml()}, продолжай работать и тебе обязательно хватит на покупку.",
|
||||||
|
ParseMode.Html);
|
||||||
|
await AnswerQuery(query.Id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _reputation.IncrementReputationAsync(Chat, From, -storeItem.Price);
|
||||||
|
await Bot.EditMessageTextAsync(Chat.Id,
|
||||||
|
messageId,
|
||||||
|
$"{From.ToHtml()} купил \"{storeItem.Name}\".",
|
||||||
|
ParseMode.Html);
|
||||||
|
|
||||||
|
var randomMedia = await mediaService!.GetRandomMediaAsync();
|
||||||
|
var file = new InputOnlineFile(randomMedia.Url);
|
||||||
|
switch (randomMedia.Type)
|
||||||
|
{
|
||||||
|
case InputMediaType.Photo:
|
||||||
|
await Bot.SendPhotoAsync(Chat.Id, file, randomMedia.Caption, replyToMessageId: messageId);
|
||||||
|
break;
|
||||||
|
case InputMediaType.Video:
|
||||||
|
await Bot.SendVideoAsync(Chat.Id, file, caption: randomMedia.Caption, replyToMessageId: messageId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await AnswerQuery(query.Id, answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetMediaService(string name, out IRandomMediaService? mediaService)
|
||||||
|
{
|
||||||
|
mediaService = _provider.GetServices<IRandomMediaService>()
|
||||||
|
.FirstOrDefault(s => s.StoreItem.Id == name);
|
||||||
|
|
||||||
|
return mediaService != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AnswerQuery(string id, string? message = null)
|
||||||
|
{
|
||||||
|
await Bot.AnswerCallbackQueryAsync(id, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
public class AnimalImage
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = null!;
|
||||||
|
public string Url { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
public class OBoobsItem
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Rank { get; set; }
|
||||||
|
public string? Author { get; set; }
|
||||||
|
public string? Model { get; set; }
|
||||||
|
public string Preview { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
public class RandomMedia
|
||||||
|
{
|
||||||
|
public RandomMedia(string url, string? caption = null)
|
||||||
|
{
|
||||||
|
Url = url;
|
||||||
|
Caption = caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Url;
|
||||||
|
public string? Caption;
|
||||||
|
|
||||||
|
public InputMediaType Type { get; set; } = InputMediaType.Photo;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
public class StoreItem
|
||||||
|
{
|
||||||
|
public string Id;
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly double Price;
|
||||||
|
|
||||||
|
public StoreItem(string id, string name, double price)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Name = name;
|
||||||
|
Price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InlineKeyboardButton ToButton(long userId)
|
||||||
|
{
|
||||||
|
return new InlineKeyboardButton($"{Name} ({Price})")
|
||||||
|
{
|
||||||
|
CallbackData = $"store|{userId}|purchase|{Id}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Service;
|
||||||
|
|
||||||
|
public class AnimBoobsService : IRandomMediaService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
public StoreItem StoreItem { get; } = new("boobs", "Сиськи движущиеся", 120);
|
||||||
|
|
||||||
|
public AnimBoobsService()
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient()
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri("https://westdev.me/_boobs/")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RandomMedia> GetRandomMediaAsync()
|
||||||
|
{
|
||||||
|
var fileName = await _httpClient.GetStringAsync("index.php");
|
||||||
|
return new RandomMedia($"https://westdev.me/_boobs/media/{fileName}")
|
||||||
|
{
|
||||||
|
Type = InputMediaType.Video
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Service;
|
||||||
|
|
||||||
|
public abstract class AnimalAsAService : IRandomMediaService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
public abstract StoreItem StoreItem { get; }
|
||||||
|
|
||||||
|
protected AnimalAsAService(Uri baseAddress)
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient
|
||||||
|
{
|
||||||
|
BaseAddress = baseAddress
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<RandomMedia> GetRandomMediaAsync()
|
||||||
|
{
|
||||||
|
var resp = await _httpClient.GetAsync("images/search");
|
||||||
|
var catImage = JsonConvert.DeserializeObject<List<AnimalImage>>(await resp.Content.ReadAsStringAsync())[0];
|
||||||
|
return new RandomMedia(catImage.Url);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Service;
|
||||||
|
|
||||||
|
public class CatApiService : AnimalAsAService
|
||||||
|
{
|
||||||
|
public override StoreItem StoreItem { get; } = new("cat", "Котэ", 40);
|
||||||
|
public CatApiService() : base(new Uri("https://api.thecatapi.com/v1/")) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Service;
|
||||||
|
|
||||||
|
public class DogApiService : AnimalAsAService
|
||||||
|
{
|
||||||
|
public override StoreItem StoreItem { get; } = new("dog", "Пёсель", 40);
|
||||||
|
public DogApiService() : base(new Uri("https://api.thedogapi.com/v1/")) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Service;
|
||||||
|
|
||||||
|
public interface IRandomMediaService
|
||||||
|
{
|
||||||
|
public StoreItem StoreItem { get; }
|
||||||
|
|
||||||
|
public Task<RandomMedia> GetRandomMediaAsync();
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using West.TelegramBot.ContentStore.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ContentStore.Service;
|
||||||
|
|
||||||
|
public class OBoobsService : IRandomMediaService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
public StoreItem StoreItem { get; } = new("boobs", "Сиськи", 60);
|
||||||
|
|
||||||
|
public OBoobsService()
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri("http://api.oboobs.ru")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RandomMedia> GetRandomMediaAsync()
|
||||||
|
{
|
||||||
|
// "/boobs/{start=0; sql offset}/{count=1; sql limit}/{order=-id;[id,rank,-rank,interest,-interest,random]}/
|
||||||
|
var httpResp = await _httpClient.GetAsync("boobs/1/1/random");
|
||||||
|
var boobsResponse = JsonConvert.DeserializeObject<List<OBoobsItem>>(await httpResp.Content.ReadAsStringAsync());
|
||||||
|
var boobsItem = boobsResponse[0];
|
||||||
|
var boobsId = boobsItem.Id.ToString("D5");
|
||||||
|
|
||||||
|
return new RandomMedia($"https://media.oboobs.ru/boobs/{boobsId}.jpg", boobsItem.Model);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user