using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Data.Sqlite; using Serilog; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; class Program { private static string _botToken = string.Empty; private static TelegramBotClient _botClient = null!; private static Dictionary usersWaitingForReport = new Dictionary(); // Отслеживаем состояние пользователей private static HashSet admins = new HashSet(); // Хранение списка администраторов private static string adminPassword = "admin123"; // Простой пароль для администратора static async Task Main() { // Загружаем конфигурацию из appsettings.json try { Log.Information("Загрузка конфигурации из appsettings.json..."); var config = new ConfigurationBuilder() .SetBasePath(AppContext.BaseDirectory) // <-- Используем правильный путь .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); _botToken = config["BotToken"] ?? throw new Exception("BotToken не найден в конфигурации!"); Log.Information("Конфигурация успешно загружена."); } catch (Exception ex) { Log.Error($"Ошибка при загрузке конфигурации: {ex.Message}"); throw; } // Настроим логирование Log.Logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); Log.Information("Запуск Telegram-бота..."); try { // Инициализация клиента бота _botClient = new TelegramBotClient(_botToken); var me = await _botClient.GetMe(); // Добавили await для получения объекта User Log.Information($"Бот {me.FirstName} запущен! ID: {me.Id}"); } catch (Exception ex) { Log.Error($"Ошибка при подключении к Telegram API: {ex.Message}"); throw; } // Создание базы данных и таблицы, если они не существуют await CreateDatabaseIfNotExists(); var cts = new CancellationTokenSource(); Log.Information("Начало получения обновлений..."); try { // Применение StartReceiving для работы с задачами _botClient.StartReceiving(HandleUpdateAsync, HandleErrorAsync, cancellationToken: cts.Token); Log.Information("Получение обновлений успешно началось."); } catch (Exception ex) { Log.Error($"Ошибка при запуске получения обновлений: {ex.Message}"); throw; } // Создание TaskCompletionSource для удержания процесса бота var tcs = new TaskCompletionSource(); await tcs.Task; // Это заставит бота работать до тех пор, пока не будет отменен // Ожидаем отмены через token cts.Token.WaitHandle.WaitOne(); } private static async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { try { if (update.Type != UpdateType.Message || update.Message?.Text == null) return; var message = update.Message; Log.Information($"Получено сообщение от {message.Chat.Id}: {message.Text}"); if (message.Text == "/start") { // Отправляем главное меню с кнопками var keyboard = new InlineKeyboardMarkup(new[] { new InlineKeyboardButton[] // Кнопки для навигации { InlineKeyboardButton.WithCallbackData("Подать заявку", "report"), InlineKeyboardButton.WithCallbackData("Просмотр заявок", "view_reports") } }); await botClient.SendMessage( chatId: message.Chat.Id, text: "Привет! Я бот для сбора заявок на ремонт оборудования.", replyMarkup: keyboard ); Log.Information($"Ответ на команду /start с кнопками отправлен."); } else if (message.Text == "report") { usersWaitingForReport[message.Chat.Id] = true; // Отметить, что пользователь должен отправить описание await botClient.SendMessage(chatId: message.Chat.Id, text: "Пожалуйста, отправьте описание проблемы."); Log.Information("Ответ на кнопку 'Подать заявку' отправлен."); } else if (admins.Contains(message.Chat.Id) && message.Text == "view_reports") { await ViewReports(botClient, message.Chat.Id); } else if (usersWaitingForReport.ContainsKey(message.Chat.Id) && usersWaitingForReport[message.Chat.Id]) { string problemDescription = message.Text; await SaveReportToDatabase(message.Chat.Id, problemDescription); await botClient.SendMessage(chatId: message.Chat.Id, text: "Спасибо за заявку! Мы обработаем её в ближайшее время."); usersWaitingForReport[message.Chat.Id] = false; Log.Information($"Заявка пользователя {message.Chat.Id} сохранена в базе данных."); } else { // Ответ на нераспознанные сообщения await botClient.SendMessage(chatId: message.Chat.Id, text: "Неизвестная команда. Используйте кнопки для навигации."); Log.Information("Ответ на неизвестную команду с кнопками отправлен."); } } catch (Exception ex) { Log.Error($"Ошибка при обработке обновлений: {ex.Message}"); Log.Error($"StackTrace: {ex.StackTrace}"); } } private static async Task SaveReportToDatabase(long chatId, string description) { string connectionString = "Data Source=bot.db"; // Используем SQLite try { using (var connection = new SqliteConnection(connectionString)) { await connection.OpenAsync(); var insertCommand = connection.CreateCommand(); insertCommand.CommandText = @" INSERT INTO Reports (ChatId, Description) VALUES (@ChatId, @Description); "; insertCommand.Parameters.AddWithValue("@ChatId", chatId); insertCommand.Parameters.AddWithValue("@Description", description); await insertCommand.ExecuteNonQueryAsync(); Log.Information($"Заявка от пользователя {chatId} успешно сохранена."); } } catch (Exception ex) { Log.Error($"Ошибка при сохранении заявки в базу данных: {ex.Message}"); } } private static async Task CreateDatabaseIfNotExists() { string connectionString = "Data Source=bot.db"; // Путь к вашей базе данных try { using (var connection = new SqliteConnection(connectionString)) { await connection.OpenAsync(); var createTableCommand = connection.CreateCommand(); createTableCommand.CommandText = @" CREATE TABLE IF NOT EXISTS Reports ( Id INTEGER PRIMARY KEY AUTOINCREMENT, ChatId INTEGER NOT NULL, Description TEXT NOT NULL, DateCreated DATETIME DEFAULT CURRENT_TIMESTAMP, Status TEXT DEFAULT 'В процессе' ); "; await createTableCommand.ExecuteNonQueryAsync(); Log.Information("Таблица Reports успешно создана (если её не было)."); } } catch (Exception ex) { Log.Error($"Ошибка при создании таблицы в базе данных: {ex.Message}"); } } private static async Task ViewReports(ITelegramBotClient botClient, long chatId) { string connectionString = "Data Source=bot.db"; // Путь к базе данных try { using (var connection = new SqliteConnection(connectionString)) { await connection.OpenAsync(); var command = connection.CreateCommand(); command.CommandText = "SELECT * FROM Reports"; using (var reader = await command.ExecuteReaderAsync()) { string reportsText = "Список заявок:\n"; while (await reader.ReadAsync()) { long id = reader.GetInt64(0); long reportChatId = reader.GetInt64(1); string description = reader.GetString(2); string status = reader.GetString(4); reportsText += $"ID: {id}, ChatId: {reportChatId}, Описание: {description}, Статус: {status}\n"; } await botClient.SendMessage(chatId: chatId, text: reportsText); } } } catch (Exception ex) { Log.Error($"Ошибка при просмотре заявок: {ex.Message}"); await botClient.SendMessage(chatId: chatId, text: "Ошибка при получении заявок."); } } private static Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken) { Log.Error($"Ошибка в процессе работы с ботом: {exception.Message}"); Log.Error($"StackTrace: {exception.StackTrace}"); return Task.CompletedTask; } }