using KLHZ.Trader.Core.Common; using KLHZ.Trader.Core.Contracts.Messaging.Dtos; using KLHZ.Trader.Core.Contracts.Messaging.Interfaces; using KLHZ.Trader.Core.Exchange.Services; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Collections.Immutable; using Telegram.Bot; using Telegram.Bot.Polling; using Telegram.Bot.Types; using Telegram.Bot.Types.ReplyMarkups; namespace KLHZ.Trader.Core.TG.Services { public class BotMessagesHandler : IUpdateHandler { private readonly ImmutableArray _admins = []; private readonly IDataBus _eventBus; private readonly ILogger _logger; private readonly PortfolioWrapper _portfolioWrapper; private readonly TraderDataProvider _traderDataProvider; public BotMessagesHandler(IDataBus eventBus, PortfolioWrapper portfolioWrapper, IOptions options, ILogger logger, TraderDataProvider traderDataProvider) { _portfolioWrapper = portfolioWrapper; _traderDataProvider = traderDataProvider; _logger = logger; _eventBus = eventBus; _admins = ImmutableArray.CreateRange(options.Value.Admins); } public Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, HandleErrorSource source, CancellationToken cancellationToken) { return Task.CompletedTask; } public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { try { if (update.Message != null && update.Message?.From != null && _admins.Contains(update.Message.From.Id)) { switch (update.Message.Text) { case "/start": { var replyKeyboardMarkup = new ReplyKeyboardMarkup(new[] { new KeyboardButton[] { Constants.BotCommandsButtons.EnableClosing2, Constants.BotCommandsButtons.DisableClosing2}, new KeyboardButton[] { Constants.BotCommandsButtons.EnableOpening2, Constants.BotCommandsButtons.EnableOpening2}}); await botClient.SendMessage(update.Message.Chat, "Принято!", replyMarkup: replyKeyboardMarkup); break; } case Constants.BotCommandsButtons.EnableClosing: case Constants.BotCommandsButtons.EnableClosing2: { BotModeSwitcher.StartClosing(); await botClient.SendMessage(update.Message.Chat, "Закрытия разрешены!"); break; } case Constants.BotCommandsButtons.DisableClosing: case Constants.BotCommandsButtons.DisableClosing2: { BotModeSwitcher.StopClosing(); await botClient.SendMessage(update.Message.Chat, "Закрытия запрещены!"); break; } case Constants.BotCommandsButtons.EnableOpening: case Constants.BotCommandsButtons.EnableOpening2: { BotModeSwitcher.StartOpening(); await botClient.SendMessage(update.Message.Chat, "Открытия начаты!"); break; } case Constants.BotCommandsButtons.DisableOpening: case Constants.BotCommandsButtons.DisableOpening2: { BotModeSwitcher.StopOpening(); await botClient.SendMessage(update.Message.Chat, "Открытия остановлены!"); break; } case "скинуть IMOEXF": case "сбросить IMOEXF": { var command = new TradeCommand() { AccountId = "", Figi = "FUTIMOEXF000", CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.ClosePosition, EnableMargin = true, Count = 1 }; await _eventBus.Broadcast(command); break; } case "лонг IMOEXF": { var command = new TradeCommand() { AccountId = "", Figi = "FUTIMOEXF000", CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.OpenLong, EnableMargin = true, Count = 1 }; await _eventBus.Broadcast(command); break; } case "шорт IMOEXF": { var command = new TradeCommand() { AccountId = "", Figi = "FUTIMOEXF000", CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.OpenShort, EnableMargin = true, Count = 1 }; await _eventBus.Broadcast(command); break; } case "stops": { var acc = _portfolioWrapper.Accounts.Values.FirstOrDefault(a => a.Assets.ContainsKey("FUTIMOEXF000")); if (acc != null) await acc.ResetStops("FUTIMOEXF000", 4, 4); break; } case "ребут": var q = Task.Run(() => { Task.Delay(1000); Environment.Exit(-1); }); return; } await botClient.SendMessage(update.Message.Chat, "Принято!"); } } catch (Exception ex) { _logger.LogError(ex, "Ошибка при обработке сообщения из телеграма."); } } } }