Files
ChatBot/ChatBot/Program.cs
Leonid Pershin 7c17127d12 fix issues
2025-10-17 03:09:11 +03:00

182 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using ChatBot.Data;
using ChatBot.Data.Interfaces;
using ChatBot.Data.Repositories;
using ChatBot.Models.Configuration;
using ChatBot.Models.Configuration.Validators;
using ChatBot.Services;
using ChatBot.Services.HealthChecks;
using ChatBot.Services.Interfaces;
using ChatBot.Services.Telegram.Commands;
using ChatBot.Services.Telegram.Interfaces;
using ChatBot.Services.Telegram.Services;
using DotNetEnv;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Serilog;
using Telegram.Bot;
// Загружаем переменные окружения из .env файла
Env.Load();
var builder = Host.CreateApplicationBuilder(args);
// Добавляем поддержку переменных окружения в конфигурацию
builder.Configuration.AddEnvironmentVariables();
// Настройка Serilog
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();
try
{
Log.ForContext<Program>().Information("Starting Telegram Bot application...");
// Добавляем Serilog в DI контейнер
builder.Services.AddSerilog();
// Конфигурируем настройки с валидацией
builder
.Services.Configure<TelegramBotSettings>(builder.Configuration.GetSection("TelegramBot"))
.AddSingleton<IValidateOptions<TelegramBotSettings>, TelegramBotSettingsValidator>();
builder
.Services.Configure<OllamaSettings>(builder.Configuration.GetSection("Ollama"))
.AddSingleton<IValidateOptions<OllamaSettings>, OllamaSettingsValidator>();
builder
.Services.Configure<AISettings>(builder.Configuration.GetSection("AI"))
.AddSingleton<IValidateOptions<AISettings>, AISettingsValidator>();
builder
.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("Database"))
.AddSingleton<IValidateOptions<DatabaseSettings>, DatabaseSettingsValidator>();
// Переопределяем настройки переменными окружения
builder.Services.Configure<TelegramBotSettings>(settings =>
{
settings.BotToken =
Environment.GetEnvironmentVariable("TELEGRAM_BOT_TOKEN") ?? settings.BotToken;
});
builder.Services.Configure<OllamaSettings>(settings =>
{
settings.Url = Environment.GetEnvironmentVariable("OLLAMA_URL") ?? settings.Url;
settings.DefaultModel =
Environment.GetEnvironmentVariable("OLLAMA_DEFAULT_MODEL") ?? settings.DefaultModel;
});
builder.Services.Configure<DatabaseSettings>(settings =>
{
var host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
var port = Environment.GetEnvironmentVariable("DB_PORT") ?? "5432";
var name = Environment.GetEnvironmentVariable("DB_NAME") ?? "chatbot";
var user = Environment.GetEnvironmentVariable("DB_USER") ?? "postgres";
var password = Environment.GetEnvironmentVariable("DB_PASSWORD") ?? "postgres";
settings.ConnectionString =
$"Host={host};Port={port};Database={name};Username={user};Password={password}";
});
// Валидируем конфигурацию при старте
builder.Services.AddOptions<TelegramBotSettings>().ValidateOnStart();
builder.Services.AddOptions<OllamaSettings>().ValidateOnStart();
builder.Services.AddOptions<AISettings>().ValidateOnStart();
builder.Services.AddOptions<DatabaseSettings>().ValidateOnStart();
// Регистрируем IOllamaClient
builder.Services.AddSingleton<IOllamaClient>(sp =>
{
var settings = sp.GetRequiredService<IOptions<OllamaSettings>>();
return new OllamaClientAdapter(settings.Value.Url);
});
// Регистрируем Entity Framework и базу данных
builder.Services.AddDbContext<ChatBotDbContext>(
(serviceProvider, options) =>
{
var dbSettings = serviceProvider.GetRequiredService<IOptions<DatabaseSettings>>().Value;
options.UseNpgsql(
dbSettings.ConnectionString,
npgsqlOptions =>
{
npgsqlOptions.CommandTimeout(dbSettings.CommandTimeout);
}
);
if (dbSettings.EnableSensitiveDataLogging)
{
options.EnableSensitiveDataLogging();
}
}
);
// Регистрируем репозиторий
builder.Services.AddScoped<IChatSessionRepository, ChatSessionRepository>();
// Регистрируем интерфейсы и сервисы
// Можно переключиться между InMemorySessionStorage и DatabaseSessionStorage
builder.Services.AddScoped<ISessionStorage, DatabaseSessionStorage>();
// Регистрируем основные сервисы
builder.Services.AddSingleton<ModelService>();
builder.Services.AddSingleton<SystemPromptService>();
builder.Services.AddSingleton<IHistoryCompressionService, HistoryCompressionService>();
builder.Services.AddSingleton<IAIService, AIService>();
builder.Services.AddScoped<ChatService>();
// Регистрируем сервис инициализации базы данных
builder.Services.AddHostedService<DatabaseInitializationService>();
// Регистрируем Telegram команды
builder.Services.AddScoped<ITelegramCommand, StartCommand>();
builder.Services.AddScoped<ITelegramCommand, HelpCommand>();
builder.Services.AddScoped<ITelegramCommand, ClearCommand>();
builder.Services.AddScoped<ITelegramCommand, SettingsCommand>();
builder.Services.AddScoped<ITelegramCommand, StatusCommand>();
// Регистрируем Telegram сервисы
builder.Services.AddSingleton<ITelegramBotClient>(provider =>
{
var settings = provider.GetRequiredService<IOptions<TelegramBotSettings>>();
return new TelegramBotClient(settings.Value.BotToken);
});
builder.Services.AddSingleton<ITelegramMessageSender, TelegramMessageSender>();
builder.Services.AddSingleton<ITelegramErrorHandler, TelegramErrorHandler>();
builder.Services.AddScoped<CommandRegistry>();
builder.Services.AddSingleton<BotInfoService>();
builder.Services.AddScoped<ITelegramCommandProcessor, TelegramCommandProcessor>();
builder.Services.AddScoped<ITelegramMessageHandler, TelegramMessageHandler>();
// Регистрируем TelegramBotService как singleton и hosted service
builder.Services.AddSingleton<ITelegramBotService, TelegramBotService>();
builder.Services.AddSingleton<IHostedService>(provider =>
(IHostedService)provider.GetRequiredService<ITelegramBotService>()
);
// Регистрируем Health Checks
var ollamaTags = new[] { "api", "ollama" };
var telegramTags = new[] { "api", "telegram" };
builder
.Services.AddHealthChecks()
.AddCheck<OllamaHealthCheck>("ollama", tags: ollamaTags)
.AddCheck<TelegramBotHealthCheck>("telegram", tags: telegramTags);
var host = builder.Build();
// Инициализируем ModelService
var modelService = host.Services.GetRequiredService<ModelService>();
await modelService.InitializeAsync();
Log.ForContext<Program>().Information("All services initialized successfully");
await host.RunAsync();
}
catch (Exception ex)
{
Log.ForContext<Program>().Fatal(ex, "Application terminated unexpectedly");
}
finally
{
await Log.CloseAndFlushAsync();
}