littleshop/LittleShop/Services/TelegramBotManagerService.cs
2025-08-27 18:02:39 +01:00

207 lines
6.4 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using LittleShop.Data;
namespace LittleShop.Services;
public class TelegramBotManagerService : BackgroundService, ITelegramBotManagerService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<TelegramBotManagerService> _logger;
private readonly ConcurrentDictionary<Guid, BotInstance> _activeBots = new();
public TelegramBotManagerService(IServiceProvider serviceProvider, ILogger<TelegramBotManagerService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("🤖 Telegram Bot Manager Service starting...");
try
{
// Load all active bots from database
await LoadActiveBotsAsync();
// Keep service running
while (!stoppingToken.IsCancellationRequested)
{
// Periodic health checks and cleanup
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
await PerformHealthChecksAsync();
}
}
catch (OperationCanceledException)
{
_logger.LogInformation("Telegram Bot Manager Service is stopping.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in Telegram Bot Manager Service");
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Telegram Bot Manager Service started");
await base.StartAsync(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Stopping all Telegram bots...");
foreach (var bot in _activeBots.Values)
{
try
{
await bot.StopAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error stopping bot {BotId}", bot.BotId);
}
}
_activeBots.Clear();
await base.StopAsync(cancellationToken);
}
public async Task<bool> AddBotAsync(Guid botId, string botToken)
{
try
{
_logger.LogInformation("Adding bot {BotId} to Telegram manager", botId);
// Validate token first
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync($"https://api.telegram.org/bot{botToken}/getMe");
if (!response.IsSuccessStatusCode)
{
_logger.LogWarning("Invalid bot token for bot {BotId}", botId);
return false;
}
// Create bot instance (placeholder for now - will implement Telegram.Bot later)
var botInstance = new BotInstance
{
BotId = botId,
BotToken = botToken,
IsRunning = false
};
_activeBots.TryAdd(botId, botInstance);
_logger.LogInformation("✅ Bot {BotId} added successfully", botId);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to add bot {BotId}", botId);
return false;
}
}
public async Task<bool> RemoveBotAsync(Guid botId)
{
if (_activeBots.TryRemove(botId, out var botInstance))
{
await botInstance.StopAsync();
_logger.LogInformation("Bot {BotId} removed from Telegram manager", botId);
return true;
}
return false;
}
public async Task<bool> UpdateBotSettingsAsync(Guid botId)
{
if (_activeBots.TryGetValue(botId, out var botInstance))
{
// Reload settings from database
_logger.LogInformation("Updating settings for bot {BotId}", botId);
return true;
}
return false;
}
public Task<int> GetActiveBotCount()
{
return Task.FromResult(_activeBots.Count(x => x.Value.IsRunning));
}
private async Task LoadActiveBotsAsync()
{
try
{
using var scope = _serviceProvider.CreateScope();
var botService = scope.ServiceProvider.GetRequiredService<IBotService>();
var activeBots = await botService.GetActiveBots();
_logger.LogInformation("Loading {Count} active bots", activeBots.Count());
foreach (var bot in activeBots)
{
// Look for telegram token in settings
if (bot.Settings.TryGetValue("telegram", out var telegramSettings) &&
telegramSettings is System.Text.Json.JsonElement telegramElement &&
telegramElement.TryGetProperty("botToken", out var tokenElement))
{
var token = tokenElement.GetString();
if (!string.IsNullOrEmpty(token) && token != "YOUR_BOT_TOKEN_HERE")
{
await AddBotAsync(bot.Id, token);
}
}
}
}
catch (Microsoft.Data.Sqlite.SqliteException ex) when (ex.Message.Contains("no such table"))
{
_logger.LogWarning("Bot tables don't exist yet. Skipping bot loading until database is fully initialized.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error loading active bots");
}
}
private async Task PerformHealthChecksAsync()
{
foreach (var kvp in _activeBots)
{
try
{
// Placeholder for health check logic
// In real implementation, would ping Telegram API
_logger.LogDebug("Health check for bot {BotId}", kvp.Key);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Health check failed for bot {BotId}", kvp.Key);
}
}
}
}
public class BotInstance
{
public Guid BotId { get; set; }
public string BotToken { get; set; } = string.Empty;
public bool IsRunning { get; set; }
public DateTime StartedAt { get; set; }
public Task StopAsync()
{
IsRunning = false;
return Task.CompletedTask;
}
}