Add customer communication system
This commit is contained in:
207
LittleShop/Services/TelegramBotManagerService.cs
Normal file
207
LittleShop/Services/TelegramBotManagerService.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user