From b7f608c8ba7ce539a231fe5997277f1d194b4e85 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Sat, 5 Jul 2025 15:35:07 +0700 Subject: [PATCH] Update bot messages --- .../Controllers/UserController.cs | 72 ++++++++++++++++++- .../ManageBot/BotService.cs | 42 ++++++++++- .../Shared/MessengerService.cs | 5 ++ .../Shared/WebhookService.cs | 21 +++++- .../src/generated/ManagingApi.ts | 35 +++++++++ .../pages/settingsPage/UserInfoSettings.tsx | 40 +++++++++-- 6 files changed, 204 insertions(+), 11 deletions(-) diff --git a/src/Managing.Api/Controllers/UserController.cs b/src/Managing.Api/Controllers/UserController.cs index 02b8cbf..9ef1b5f 100644 --- a/src/Managing.Api/Controllers/UserController.cs +++ b/src/Managing.Api/Controllers/UserController.cs @@ -17,6 +17,7 @@ public class UserController : BaseController { private IConfiguration _config; private readonly IJwtUtils _jwtUtils; + private readonly IWebhookService _webhookService; /// /// Initializes a new instance of the class. @@ -24,11 +25,13 @@ public class UserController : BaseController /// Configuration settings. /// Service for user-related operations. /// Utility for JWT token operations. - public UserController(IConfiguration config, IUserService userService, IJwtUtils jwtUtils) + /// Service for webhook operations. + public UserController(IConfiguration config, IUserService userService, IJwtUtils jwtUtils, IWebhookService webhookService) : base(userService) { _config = config; _jwtUtils = jwtUtils; + _webhookService = webhookService; } /// @@ -98,7 +101,74 @@ public class UserController : BaseController { var user = await GetUser(); var updatedUser = await _userService.UpdateTelegramChannel(user, telegramChannel); + + // Send welcome message to the newly configured telegram channel + if (!string.IsNullOrEmpty(telegramChannel)) + { + try + { + var welcomeMessage = $"🎉 **Trading Bot - Welcome!**\n\n" + + $"┌─────────────────────────────┐\n" + + $"│ CHANNEL CONFIGURED ✅ │\n" + + $"└─────────────────────────────┘\n\n" + + $"🎯 **Agent:** {user.Name}\n" + + $"📡 **Channel ID:** {telegramChannel}\n" + + $"⏰ **Setup Time:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" + + $"🔔 **Notification Types:**\n" + + $"• 📈 Position Opens & Closes\n" + + $"• 🤖 Bot configuration changes\n\n" + + $"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + + $"🚀 **Welcome aboard!** Your trading notifications are now live."; + + await _webhookService.SendMessage(welcomeMessage, telegramChannel); + } + catch (Exception ex) + { + // Log the error but don't fail the update operation + Console.WriteLine($"Failed to send welcome message to telegram channel {telegramChannel}: {ex.Message}"); + } + } + return Ok(updatedUser); } + + /// + /// Tests the Telegram channel configuration by sending a test message. + /// + /// A message indicating the test result. + [HttpPost("telegram-channel/test")] + public async Task> TestTelegramChannel() + { + var user = await GetUser(); + + if (string.IsNullOrEmpty(user.TelegramChannel)) + { + return BadRequest("No Telegram channel configured for this user. Please set a Telegram channel first."); + } + + try + { + var testMessage = $"🚀 **Trading Bot - Channel Test**\n\n" + + $"┌─────────────────────────────┐\n" + + $"│ CONNECTION SUCCESSFUL ✅ │\n" + + $"└─────────────────────────────┘\n\n" + + $"🎯 **Agent:** {user.Name}\n" + + $"📡 **Channel ID:** {user.TelegramChannel}\n" + + $"⏰ **Test Time:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" + + $"🔔 **You will receive notifications for:**\n" + + $"• 📈 Position Opens & Closes\n" + + $"• 🤖 Bot configuration changes\n\n" + + $"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + + $"🎉 **Ready to trade!** Your notifications are now active."; + + await _webhookService.SendMessage(testMessage, user.TelegramChannel); + + return Ok($"Test message sent successfully to Telegram channel {user.TelegramChannel}. Please check your Telegram to verify delivery."); + } + catch (Exception ex) + { + return StatusCode(500, $"Failed to send test message: {ex.Message}"); + } + } } \ No newline at end of file diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs index e95c9a6..1377ce0 100644 --- a/src/Managing.Application/ManageBot/BotService.cs +++ b/src/Managing.Application/ManageBot/BotService.cs @@ -188,6 +188,18 @@ namespace Managing.Application.ManageBot { await Task.Run(() => bot.Stop()); // Assuming Stop is an asynchronous process wrapped in Task.Run for synchronous methods + + var stopMessage = $"🛑 **Bot Stopped**\n\n" + + $"┌─────────────────────────────┐\n" + + $"│ BOT STOPPED 🔴 │\n" + + $"└─────────────────────────────┘\n\n" + + $"🎯 **Agent:** {bot.User.AgentName}\n" + + $"🤖 **Bot Name:** {bot.Name}\n" + + $"⏰ **Stopped At:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" + + $"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + + $"✅ **Bot has been safely stopped and is no longer active.**"; + + await _messengerService.SendTradeMessage(stopMessage, false, bot.User); return bot.GetStatus(); } } @@ -205,6 +217,18 @@ namespace Managing.Application.ManageBot { await Task.Run(() => bot.Stop()); // Assuming Stop is an asynchronous process wrapped in Task.Run for synchronous methods + + var deleteMessage = $"🗑️ **Bot Deleted**\n\n" + + $"┌─────────────────────────────┐\n" + + $"│ BOT DELETED ❌ │\n" + + $"└─────────────────────────────┘\n\n" + + $"🎯 **Agent:** {bot.User.AgentName}\n" + + $"🤖 **Bot Name:** {bot.Name}\n" + + $"⏰ **Deleted At:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" + + $"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + + $"⚠️ **Bot has been permanently deleted and all data removed.**"; + + await _messengerService.SendTradeMessage(deleteMessage, false, bot.User); } await _botRepository.DeleteBotBackup(identifier); @@ -220,18 +244,30 @@ namespace Managing.Application.ManageBot return false; } - public Task RestartBot(string identifier) + public async Task RestartBot(string identifier) { if (_botTasks.TryGetValue(identifier, out var botWrapper)) { if (botWrapper.BotInstance is IBot bot) { bot.Restart(); - return Task.FromResult(bot.GetStatus()); + + var restartMessage = $"🔄 **Bot Restarted**\n\n" + + $"┌─────────────────────────────┐\n" + + $"│ BOT RESTARTED 🟢 │\n" + + $"└─────────────────────────────┘\n\n" + + $"🎯 **Agent:** {bot.User.AgentName}\n" + + $"🤖 **Bot Name:** {bot.Name}\n" + + $"⏰ **Restarted At:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" + + $"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + + $"🚀 **Bot has been successfully restarted and is now active.**"; + + await _messengerService.SendTradeMessage(restartMessage, false, bot.User); + return bot.GetStatus(); } } - return Task.FromResult(BotStatus.Down.ToString()); + return BotStatus.Down.ToString(); } public void ToggleIsForWatchingOnly(string identifier) diff --git a/src/Managing.Application/Shared/MessengerService.cs b/src/Managing.Application/Shared/MessengerService.cs index 7af1cda..46bd70d 100644 --- a/src/Managing.Application/Shared/MessengerService.cs +++ b/src/Managing.Application/Shared/MessengerService.cs @@ -68,6 +68,11 @@ public class MessengerService : IMessengerService } } + public async Task SendMessage(string message, string telegramChannel) + { + await _webhookService.SendMessage(message, telegramChannel); + } + private string BuildPositionMessage(Position position) { var direction = position.OriginDirection.ToString(); diff --git a/src/Managing.Application/Shared/WebhookService.cs b/src/Managing.Application/Shared/WebhookService.cs index 4263af2..72cd66f 100644 --- a/src/Managing.Application/Shared/WebhookService.cs +++ b/src/Managing.Application/Shared/WebhookService.cs @@ -77,7 +77,7 @@ public class WebhookService : IWebhookService message = message, timestamp = DateTime.UtcNow, type = "general_message", - telegramChannel = telegramChannel + telegramChannel = FormatTelegramChannel(telegramChannel) }; // Send the webhook notification @@ -97,4 +97,23 @@ public class WebhookService : IWebhookService _logger.LogError(ex, "Error sending webhook message"); } } + + private string FormatTelegramChannel(string? telegramChannel) + { + if (string.IsNullOrEmpty(telegramChannel)) + { + return string.Empty; + } + + if (telegramChannel.StartsWith("100")) + { + return telegramChannel.Substring(3); + } + else if (telegramChannel.StartsWith("-100")) + { + return telegramChannel.Substring(4); + } + + return telegramChannel; + } } \ No newline at end of file diff --git a/src/Managing.WebApp/src/generated/ManagingApi.ts b/src/Managing.WebApp/src/generated/ManagingApi.ts index 24dfbee..90977d2 100644 --- a/src/Managing.WebApp/src/generated/ManagingApi.ts +++ b/src/Managing.WebApp/src/generated/ManagingApi.ts @@ -2598,6 +2598,41 @@ export class UserClient extends AuthorizedApiBase { } return Promise.resolve(null as any); } + + user_TestTelegramChannel(): Promise { + let url_ = this.baseUrl + "/User/telegram-channel/test"; + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.transformOptions(options_).then(transformedOptions_ => { + return this.http.fetch(url_, transformedOptions_); + }).then((_response: Response) => { + return this.processUser_TestTelegramChannel(_response); + }); + } + + protected processUser_TestTelegramChannel(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as string; + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null as any); + } } export class WorkflowClient extends AuthorizedApiBase { diff --git a/src/Managing.WebApp/src/pages/settingsPage/UserInfoSettings.tsx b/src/Managing.WebApp/src/pages/settingsPage/UserInfoSettings.tsx index d6aeb46..28dc729 100644 --- a/src/Managing.WebApp/src/pages/settingsPage/UserInfoSettings.tsx +++ b/src/Managing.WebApp/src/pages/settingsPage/UserInfoSettings.tsx @@ -88,6 +88,24 @@ function UserInfoSettings() { } } + const testTelegramChannel = async () => { + if (!user?.telegramChannel) { + const toast = new Toast('No telegram channel configured') + toast.update('error', 'Please configure a telegram channel first') + return + } + + const toast = new Toast('Testing telegram channel...') + try { + const response = await api.user_TestTelegramChannel() + toast.update('success', 'Test message sent! Check your Telegram.') + } catch (error: any) { + console.error('Error testing telegram channel:', error) + const errorMessage = error.response?.data || error.message || 'Failed to send test message' + toast.update('error', errorMessage) + } + } + return (
@@ -136,12 +154,22 @@ function UserInfoSettings() {

{user?.telegramChannel || 'Not set'}

- +
+ + {user?.telegramChannel && ( + + )} +