mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
[quote] Crappy chat quote implementation.
This commit is contained in:
+25
-10
@@ -1,25 +1,29 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{B41CB31A-641E-4079-87ED-5CE310B2D8C1}"
|
VisualStudioVersion = 17.0.32112.339
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "Core\Core.csproj", "{B41CB31A-641E-4079-87ED-5CE310B2D8C1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{C7821F15-DEDD-474F-A575-A296D4B58F10}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{C7821F15-DEDD-474F-A575-A296D4B58F10}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CombotAntiSpam", "modules\CombotAntiSpam\CombotAntiSpam.csproj", "{F1E1FBB7-ABA4-4304-9A42-D4975822B002}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CombotAntiSpam", "modules\CombotAntiSpam\CombotAntiSpam.csproj", "{F1E1FBB7-ABA4-4304-9A42-D4975822B002}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RichSiteSummary", "modules\RichSiteSummary\RichSiteSummary.csproj", "{C50D64C3-204B-4B58-927B-C8D759787252}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RichSiteSummary", "modules\RichSiteSummary\RichSiteSummary.csproj", "{C50D64C3-204B-4B58-927B-C8D759787252}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "tests\Tests.csproj", "{5C62CA70-F270-4029-953E-458623C31A3B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "tests\Tests.csproj", "{5C62CA70-F270-4029-953E-458623C31A3B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UrlLimitations", "modules\UrlLimitations\UrlLimitations.csproj", "{B82E3339-3B34-4600-8C59-C5A3640B1982}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UrlLimitations", "modules\UrlLimitations\UrlLimitations.csproj", "{B82E3339-3B34-4600-8C59-C5A3640B1982}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Destiny2.WhereIsXur", "modules\Destiny2.WhereIsXur\Destiny2.WhereIsXur.csproj", "{AE782132-BED8-4D1E-98FA-CB768171D332}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Destiny2.WhereIsXur", "modules\Destiny2.WhereIsXur\Destiny2.WhereIsXur.csproj", "{AE782132-BED8-4D1E-98FA-CB768171D332}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatManagement", "modules\ChatManagement\ChatManagement.csproj", "{55ACF7F7-409A-45EE-A41D-D8417DE7EAA7}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatManagement", "modules\ChatManagement\ChatManagement.csproj", "{55ACF7F7-409A-45EE-A41D-D8417DE7EAA7}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserGroupTag", "modules\UserGroupTag\UserGroupTag.csproj", "{5B89E22A-78CF-4037-BE0D-5F88EF47022B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserGroupTag", "modules\UserGroupTag\UserGroupTag.csproj", "{5B89E22A-78CF-4037-BE0D-5F88EF47022B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entertainment", "modules\Entertainment\Entertainment.csproj", "{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Entertainment", "modules\Entertainment\Entertainment.csproj", "{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatQuotes", "modules\ChatQuotes\ChatQuotes.csproj", "{04F16325-8F44-4250-9B2E-0F77E8F65CBF}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -63,6 +67,13 @@ Global
|
|||||||
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1D62101B-C2B1-4E79-8F7A-690E44E3EE81}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{04F16325-8F44-4250-9B2E-0F77E8F65CBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{04F16325-8F44-4250-9B2E-0F77E8F65CBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{04F16325-8F44-4250-9B2E-0F77E8F65CBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{04F16325-8F44-4250-9B2E-0F77E8F65CBF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{F1E1FBB7-ABA4-4304-9A42-D4975822B002} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
{F1E1FBB7-ABA4-4304-9A42-D4975822B002} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
@@ -72,5 +83,9 @@ Global
|
|||||||
{55ACF7F7-409A-45EE-A41D-D8417DE7EAA7} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
{55ACF7F7-409A-45EE-A41D-D8417DE7EAA7} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
{5B89E22A-78CF-4037-BE0D-5F88EF47022B} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
{5B89E22A-78CF-4037-BE0D-5F88EF47022B} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
|
||||||
{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}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {5BA73C3B-D5FC-4942-9091-504325CDC308}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Kruzya.TelegramBot.Core;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using West.TelegramBot.ChatQuotes.Json;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes
|
||||||
|
{
|
||||||
|
public class ChatQuotes : Module
|
||||||
|
{
|
||||||
|
public static readonly JsonSerializerSettings SerializerSettings = new()
|
||||||
|
{
|
||||||
|
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||||
|
DateParseHandling = DateParseHandling.None,
|
||||||
|
Converters =
|
||||||
|
{
|
||||||
|
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal },
|
||||||
|
new StringEnumConverter(new CamelCaseNamingStrategy())
|
||||||
|
},
|
||||||
|
ContractResolver = new NullToEmptyObjectResolver()
|
||||||
|
};
|
||||||
|
|
||||||
|
public ChatQuotes(Core core) : base(core) { }
|
||||||
|
|
||||||
|
public override void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<QuoteGeneratorService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>West.TelegramBot.ChatQuotes</RootNamespace>
|
||||||
|
<AssemblyName>TelegramBot.ChatQuotes</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Handler\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Core\Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
<Delete Files="$(OutDir)\TelegramBot.dll" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using BotFramework;
|
||||||
|
using BotFramework.Attributes;
|
||||||
|
using BotFramework.Enums;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types.InputFiles;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes.Handler;
|
||||||
|
|
||||||
|
public class Quote : BotEventHandler
|
||||||
|
{
|
||||||
|
private readonly QuoteGeneratorService _quoteGenerator;
|
||||||
|
|
||||||
|
public Quote(QuoteGeneratorService quoteGenerator)
|
||||||
|
{
|
||||||
|
_quoteGenerator = quoteGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(InChat.Public, "q", CommandParseMode.Both)]
|
||||||
|
public async Task HandleQuote()
|
||||||
|
{
|
||||||
|
var msg = RawUpdate.Message;
|
||||||
|
var replyToMessage = msg?.ReplyToMessage;
|
||||||
|
if (msg == null || replyToMessage == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = new InputOnlineFile(await _quoteGenerator.GenerateQuoteImage(replyToMessage));
|
||||||
|
await Bot.SendStickerAsync(Chat.Id, file, replyToMessageId: msg.MessageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes.Json
|
||||||
|
{
|
||||||
|
class NullToEmptyObjectResolver : DefaultContractResolver
|
||||||
|
{
|
||||||
|
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||||
|
{
|
||||||
|
return type.GetProperties()
|
||||||
|
.Select(p => {
|
||||||
|
var jp = base.CreateProperty(p, memberSerialization);
|
||||||
|
jp.ValueProvider = new NullToEmptyStringValueProvider(p);
|
||||||
|
return jp;
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes.Json;
|
||||||
|
|
||||||
|
public class NullToEmptyStringValueProvider : IValueProvider
|
||||||
|
{
|
||||||
|
private readonly PropertyInfo _memberInfo;
|
||||||
|
public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
|
||||||
|
{
|
||||||
|
_memberInfo = memberInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? GetValue(object target)
|
||||||
|
{
|
||||||
|
var result = _memberInfo.GetValue(target);
|
||||||
|
if (_memberInfo.PropertyType == typeof(Message) && result == null) result = new object();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(object target, object value)
|
||||||
|
{
|
||||||
|
_memberInfo.SetValue(target, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using File = Telegram.Bot.Types.File;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes.Model;
|
||||||
|
|
||||||
|
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
||||||
|
public class QuoteRequest
|
||||||
|
{
|
||||||
|
public QuoteRequest(Message msg)
|
||||||
|
{
|
||||||
|
// TODO: move default values to config
|
||||||
|
Format = "webp";
|
||||||
|
BackgroundColor = "#1b1429";
|
||||||
|
Width = 512;
|
||||||
|
Height = 768;
|
||||||
|
Scale = 2;
|
||||||
|
|
||||||
|
Messages = new List<QuoteMessage> {QuoteMessage.FromMessage(msg)};
|
||||||
|
}
|
||||||
|
|
||||||
|
public QuoteType Type { get; set; }
|
||||||
|
public string Format { get; set; }
|
||||||
|
public string BackgroundColor { get; set; }
|
||||||
|
public int Width { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
public int Scale { get; set; }
|
||||||
|
public List<QuoteMessage>? Messages { get; set; }
|
||||||
|
|
||||||
|
public string ToJson()
|
||||||
|
{
|
||||||
|
return JsonConvert.SerializeObject(this, ChatQuotes.SerializerSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
||||||
|
public class QuoteMessage
|
||||||
|
{
|
||||||
|
public List<File>? Media { get; set; }
|
||||||
|
public QuoteMediaType? MediaType { get; set; }
|
||||||
|
public long ChatId { get; set; }
|
||||||
|
public bool Avatar { get; set; } = true;
|
||||||
|
public User? From { get; set; }
|
||||||
|
public string? Text { get; set; }
|
||||||
|
public Message? ReplyMessage { get; set; }
|
||||||
|
|
||||||
|
public static QuoteMessage FromMessage(Message msg)
|
||||||
|
{
|
||||||
|
var quoteMessage = new QuoteMessage();
|
||||||
|
|
||||||
|
if (msg.Text != null)
|
||||||
|
{
|
||||||
|
quoteMessage.Text = msg.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sticker = msg.Sticker;
|
||||||
|
if (sticker != null)
|
||||||
|
{
|
||||||
|
var file = new File
|
||||||
|
{
|
||||||
|
FileId = sticker.FileId,
|
||||||
|
FileSize = sticker.FileSize,
|
||||||
|
FileUniqueId = sticker.FileUniqueId
|
||||||
|
};
|
||||||
|
quoteMessage.Media = new List<File> {file};
|
||||||
|
quoteMessage.MediaType = QuoteMediaType.Sticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
quoteMessage.ChatId = msg.Chat.Id;
|
||||||
|
quoteMessage.ReplyMessage = msg.ReplyToMessage;
|
||||||
|
quoteMessage.From = User.FromTgUser(msg.From!);
|
||||||
|
|
||||||
|
return quoteMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum QuoteMediaType
|
||||||
|
{
|
||||||
|
Sticker = 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes.Model;
|
||||||
|
|
||||||
|
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
||||||
|
public class QuoteResponse
|
||||||
|
{
|
||||||
|
public bool Ok { get; set; }
|
||||||
|
|
||||||
|
public Result Result { get; set; }
|
||||||
|
public static QuoteResponse FromJson(string json)
|
||||||
|
=> JsonConvert.DeserializeObject<QuoteResponse>(json, ChatQuotes.SerializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
||||||
|
public class Result
|
||||||
|
{
|
||||||
|
public string Image { get; set; }
|
||||||
|
|
||||||
|
public QuoteType Type { get; set; }
|
||||||
|
|
||||||
|
public long Width { get; set; }
|
||||||
|
|
||||||
|
public long Height { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum QuoteType
|
||||||
|
{
|
||||||
|
Quote = 0,
|
||||||
|
Image,
|
||||||
|
Null
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes.Model;
|
||||||
|
|
||||||
|
public class User : Telegram.Bot.Types.User
|
||||||
|
{
|
||||||
|
[JsonProperty]
|
||||||
|
public string Name => LastName != null ? $"{FirstName} {LastName}" : FirstName;
|
||||||
|
|
||||||
|
public static User FromTgUser(Telegram.Bot.Types.User user)
|
||||||
|
{
|
||||||
|
return new User
|
||||||
|
{
|
||||||
|
Id = user.Id,
|
||||||
|
FirstName = user.FirstName,
|
||||||
|
LastName = user.LastName,
|
||||||
|
Username = user.Username,
|
||||||
|
LanguageCode = user.LanguageCode,
|
||||||
|
IsBot = user.IsBot
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using West.TelegramBot.ChatQuotes.Model;
|
||||||
|
|
||||||
|
namespace West.TelegramBot.ChatQuotes;
|
||||||
|
|
||||||
|
public class QuoteGeneratorService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
|
public QuoteGeneratorService(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri(configuration.GetValue<string>("QuoteApiUrl"))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Stream> GenerateQuoteImage(Message msg)
|
||||||
|
{
|
||||||
|
var request = new QuoteRequest(msg);
|
||||||
|
var content = new ByteArrayContent(Encoding.UTF8.GetBytes(request.ToJson().ToCharArray()))
|
||||||
|
{
|
||||||
|
Headers =
|
||||||
|
{
|
||||||
|
ContentType = MediaTypeHeaderValue.Parse("application/json")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var resp = await _httpClient.PostAsync("/generate", content);
|
||||||
|
var quoteResponse = JsonConvert.DeserializeObject<QuoteResponse>(await resp.Content.ReadAsStringAsync());
|
||||||
|
|
||||||
|
return new MemoryStream(Convert.FromBase64String(quoteResponse.Result.Image));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user