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 System.Net.NetworkInformation; using Telegram.Bot.Types.Enums; using Ping = Kruzya.TelegramBot.CustomChatAddOns.Data.Ping; 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(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"); } } }