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.EnableSelling, Constants.BotCommandsButtons.DisableSelling}, new KeyboardButton[] { Constants.BotCommandsButtons.EnablePurchases, Constants.BotCommandsButtons.DisablePurchases}}); await botClient.SendMessage(update.Message.Chat, "Принято!", replyMarkup: replyKeyboardMarkup); break; } case Constants.BotCommandsButtons.EnableSelling: { BotModeSwitcher.StartSelling(); await botClient.SendMessage(update.Message.Chat, "Продажи начаты!"); break; } case Constants.BotCommandsButtons.DisableSelling: { BotModeSwitcher.StopSelling(); await botClient.SendMessage(update.Message.Chat, "Продажи остановлены!"); break; } case Constants.BotCommandsButtons.EnablePurchases: { BotModeSwitcher.StartPurchase(); await botClient.SendMessage(update.Message.Chat, "Покупки начаты!"); break; } case Constants.BotCommandsButtons.DisablePurchases: { BotModeSwitcher.StopPurchase(); 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, "Ошибка при обработке сообщения из телеграма."); } } } }