mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
move to correct directory
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using Kruzya.TelegramBot.Core;
|
||||
using Kruzya.TelegramBot.Core.Extensions;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns
|
||||
{
|
||||
public class CustomChatAddOns : Module
|
||||
{
|
||||
public CustomChatAddOns(Core.Core core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddOption<CustomChatHandler>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyName>TelegramBot.CustomChatAddOns</AssemblyName>
|
||||
<RootNamespace>Kruzya.TelegramBot.CustomChatAddOns</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.InputFile
|
||||
{
|
||||
public interface ICustomInputFile
|
||||
{
|
||||
public IInputFile Convert();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Kruzya.TelegramBot.Core.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.InputFile
|
||||
{
|
||||
[AllowedSerializableType("input_id_file")]
|
||||
public class InputIdFile : ICustomInputFile
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
public IInputFile Convert()
|
||||
{
|
||||
return new InputFileId(Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Kruzya.TelegramBot.Core.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.InputFile
|
||||
{
|
||||
[AllowedSerializableType("input_url_file")]
|
||||
public class InputUrlFile : ICustomInputFile
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; } = "";
|
||||
|
||||
public IInputFile Convert()
|
||||
{
|
||||
return new InputFileUrl(Url);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Kruzya.TelegramBot.Core.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data
|
||||
{
|
||||
[AllowedSerializableType("new_message")]
|
||||
public class NewMessage
|
||||
{
|
||||
[JsonProperty("message")]
|
||||
public Message Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Kruzya.TelegramBot.Core.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data
|
||||
{
|
||||
[AllowedSerializableType("ping")]
|
||||
public class Ping
|
||||
{
|
||||
[JsonProperty("chat_id")]
|
||||
public long ChatId { get; set; }
|
||||
|
||||
[JsonProperty("user_id")]
|
||||
public long UserId { get; set; }
|
||||
|
||||
[JsonProperty("confirmation")]
|
||||
public string Confirmation { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
public static Ping From(Message message) => new() {
|
||||
ChatId = message.Chat.Id,
|
||||
UserId = message.From!.Id
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Kruzya.TelegramBot.Core.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data
|
||||
{
|
||||
[AllowedSerializableType("pong")]
|
||||
public class Pong
|
||||
{
|
||||
[JsonProperty("confirmation")]
|
||||
public string Confirmation { get; set; } = Guid.NewGuid().ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.WebhookCommand
|
||||
{
|
||||
public abstract class BaseReplyMessage
|
||||
{
|
||||
[JsonProperty("content")]
|
||||
public string Content { get; set; }
|
||||
|
||||
[JsonProperty("parse_mode")]
|
||||
public ParseMode? ParseMode { get; set; }
|
||||
|
||||
[JsonProperty("disable_notification")]
|
||||
public bool? DisableNotification { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.WebhookCommand
|
||||
{
|
||||
public interface IWebhookCommand
|
||||
{
|
||||
public Task Execute(ITelegramBotClient botClient, Message message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Data.InputFile;
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.WebhookCommand
|
||||
{
|
||||
public class PhotoReplyMessage : BaseReplyMessage, IWebhookCommand
|
||||
{
|
||||
[JsonProperty("photo")]
|
||||
public ICustomInputFile Photo { get; set; }
|
||||
|
||||
public async Task Execute(ITelegramBotClient botClient, Message message)
|
||||
{
|
||||
await botClient.SendPhotoAsync(message.Chat.Id, Photo.Convert(),
|
||||
caption: Content, parseMode: ParseMode,
|
||||
disableNotification: DisableNotification);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Kruzya.TelegramBot.Core.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Data.WebhookCommand
|
||||
{
|
||||
[AllowedSerializableType("text_reply_message")]
|
||||
public class TextReplyMessage : BaseReplyMessage, IWebhookCommand
|
||||
{
|
||||
[JsonProperty("disable_web_page_preview")]
|
||||
public bool? DisableWebPagePreview { get; set; }
|
||||
|
||||
public async Task Execute(ITelegramBotClient botClient, Message message)
|
||||
{
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Content,
|
||||
parseMode: ParseMode, disableNotification: DisableNotification,
|
||||
disableWebPagePreview: DisableWebPagePreview);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using BotFramework.Attributes;
|
||||
using Kruzya.TelegramBot.Core.Data;
|
||||
using Kruzya.TelegramBot.Core.Extensions;
|
||||
using Kruzya.TelegramBot.Core.Handler;
|
||||
using Kruzya.TelegramBot.Core.Service;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Data;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Options;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Service;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Handler
|
||||
{
|
||||
public class Config : CommonHandler
|
||||
{
|
||||
private readonly CustomChatHandler _option;
|
||||
private readonly UserService _userService;
|
||||
private readonly InteropService _interopService;
|
||||
|
||||
public Config(CustomChatHandler option, UserService userService, InteropService interopService, CoreContext db) : base(db)
|
||||
{
|
||||
_option = option;
|
||||
_userService = userService;
|
||||
_interopService = interopService;
|
||||
}
|
||||
|
||||
private bool IsAllowedChatType(ChatType chatType)
|
||||
{
|
||||
// TODO: move to class constant.
|
||||
var allowedChatTypes = new[] { ChatType.Supergroup, ChatType.Group, ChatType.Channel };
|
||||
return allowedChatTypes.Contains(chatType);
|
||||
}
|
||||
|
||||
[ParametrizedCommand("set_custom_handler")]
|
||||
public async Task Handle(Uri endpoint)
|
||||
{
|
||||
if (!IsAllowedChatType(Chat.Type))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await Bot.IsUserAdminAsync(Chat, From))
|
||||
{
|
||||
await Reply("Sorry, you cannot do this");
|
||||
return;
|
||||
}
|
||||
|
||||
// URLs to somewhere in local bot network should be allowed for using only super-admins.
|
||||
// It may be bypassed via using, for example, "kitties" instead of "kitties.bot.svc.cluster.local". Maybe check resulting IP?
|
||||
if (endpoint.Host.EndsWith(".local") && !_userService.IsUserSuper(From.Id))
|
||||
{
|
||||
await Reply("Sorry, you cannot do this");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var ping = Ping.From(Message!);
|
||||
var pong = await _interopService.PostMessage<Ping, Pong>(endpoint.ToString(), ping);
|
||||
if (pong.Confirmation != ping.Confirmation)
|
||||
{
|
||||
throw new Exception("Invalid response");
|
||||
}
|
||||
}
|
||||
// catch (HttpRequestException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
await Reply($"Sorry, this URL cannot be set as chat webhook: {e.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
await _option.SetValueAsync(Chat.Id, endpoint.ToString());
|
||||
await Reply("Done, configured");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using BotFramework;
|
||||
using BotFramework.Attributes;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Data;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Data.WebhookCommand;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Options;
|
||||
using Kruzya.TelegramBot.CustomChatAddOns.Service;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Handler
|
||||
{
|
||||
public class MessageHandler : BotEventHandler
|
||||
{
|
||||
private readonly CustomChatHandler _option;
|
||||
private readonly InteropService _interopService;
|
||||
|
||||
public MessageHandler(CustomChatHandler option, InteropService interopService)
|
||||
{
|
||||
_option = option;
|
||||
_interopService = interopService;
|
||||
}
|
||||
|
||||
[Message]
|
||||
[Priority(short.MinValue + 10)]
|
||||
public async Task DeliverMessage()
|
||||
{
|
||||
var message = RawUpdate.Message;
|
||||
if (message == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var url = await _option.GetValueAsync(Chat.Id);
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commands = await _interopService.PostMessage<NewMessage, List<IWebhookCommand>>(url, new() { Message = message });
|
||||
foreach (var command in commands)
|
||||
{
|
||||
await command.Execute(Bot, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Kruzya.TelegramBot.Core.Options;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Options
|
||||
{
|
||||
public class CustomChatHandler : AbstractOption<CustomChatHandler, string>
|
||||
{
|
||||
public CustomChatHandler(IOptionProvider optionProvider) : base(optionProvider)
|
||||
{
|
||||
}
|
||||
|
||||
public override string OptionId => "customChatHandlerUrl";
|
||||
|
||||
public override string OptionName => "Custom Chat Handler";
|
||||
|
||||
public override OptionType OptionType => OptionType.Hidden;
|
||||
|
||||
public override string DefaultValue => "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.CustomChatAddOns.Service
|
||||
{
|
||||
public class InteropService
|
||||
{
|
||||
private readonly JsonSerializerSettings _serializerSettings;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public InteropService(ISerializationBinder serializationBinder, HttpClient client)
|
||||
{
|
||||
_serializerSettings = new()
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Objects,
|
||||
SerializationBinder = serializationBinder
|
||||
};
|
||||
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public async Task<TOut> PostMessage<TIn, TOut>(string endpoint, TIn message)
|
||||
{
|
||||
var serializedMessage = JsonConvert.SerializeObject(message, _serializerSettings);
|
||||
var httpContent = new StringContent(serializedMessage, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await (await _client.PostAsync(endpoint, httpContent))
|
||||
.EnsureSuccessStatusCode()
|
||||
.Content.ReadAsStringAsync();
|
||||
|
||||
return JsonConvert.DeserializeObject<TOut>(response, _serializerSettings)!;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user