207 lines
6.4 KiB
C#
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;
|
|
}
|
|
} |