2025-03-12 17:52:00 +07:00
|
|
|
|
using System;
|
2025-03-17 14:53:01 +07:00
|
|
|
|
using System.Collections.Generic;
|
2025-03-12 17:52:00 +07:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
class Program
|
|
|
|
|
{
|
|
|
|
|
private static string _botToken = string.Empty;
|
|
|
|
|
private static TelegramBotClient _botClient = null!;
|
2025-03-17 14:53:01 +07:00
|
|
|
|
private static Dictionary<long, bool> usersWaitingForReport = new Dictionary<long, bool>(); // Отслеживаем состояние пользователей
|
2025-03-17 15:33:06 +07:00
|
|
|
|
private static HashSet<long> admins = new HashSet<long>(); // Хранение списка администраторов
|
|
|
|
|
private static string adminPassword = "admin123"; // Простой пароль для администратора
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
|
|
|
|
static async Task Main()
|
|
|
|
|
{
|
|
|
|
|
// Загружаем конфигурацию из appsettings.json
|
2025-03-12 22:41:14 +07:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Log.Information("Загрузка конфигурации из appsettings.json...");
|
|
|
|
|
var config = new ConfigurationBuilder()
|
|
|
|
|
.SetBasePath(AppContext.BaseDirectory) // <-- Используем правильный путь
|
|
|
|
|
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
|
|
|
|
.Build();
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
2025-03-12 22:41:14 +07:00
|
|
|
|
_botToken = config["BotToken"] ?? throw new Exception("BotToken не найден в конфигурации!");
|
|
|
|
|
Log.Information("Конфигурация успешно загружена.");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error($"Ошибка при загрузке конфигурации: {ex.Message}");
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
2025-03-17 14:53:01 +07:00
|
|
|
|
// Настроим логирование
|
2025-03-12 17:52:00 +07:00
|
|
|
|
Log.Logger = new LoggerConfiguration()
|
|
|
|
|
.WriteTo.Console()
|
|
|
|
|
.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
|
|
|
|
|
.CreateLogger();
|
|
|
|
|
|
|
|
|
|
Log.Information("Запуск Telegram-бота...");
|
|
|
|
|
|
2025-03-12 22:41:14 +07:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// Инициализация клиента бота
|
|
|
|
|
_botClient = new TelegramBotClient(_botToken);
|
2025-03-17 14:53:01 +07:00
|
|
|
|
var me = await _botClient.GetMeAsync();
|
2025-03-12 22:41:14 +07:00
|
|
|
|
Log.Information($"Бот {me.FirstName} запущен! ID: {me.Id}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error($"Ошибка при подключении к Telegram API: {ex.Message}");
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
2025-03-17 15:07:41 +07:00
|
|
|
|
// Создание базы данных и таблицы, если они не существуют
|
|
|
|
|
await CreateDatabaseIfNotExists();
|
|
|
|
|
|
2025-03-12 19:11:38 +07:00
|
|
|
|
var cts = new CancellationTokenSource();
|
2025-03-12 22:41:14 +07:00
|
|
|
|
Log.Information("Начало получения обновлений...");
|
2025-03-12 22:17:34 +07:00
|
|
|
|
|
2025-03-12 22:41:14 +07:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// Применение StartReceiving для работы с задачами
|
|
|
|
|
_botClient.StartReceiving(HandleUpdateAsync, HandleErrorAsync, cancellationToken: cts.Token);
|
|
|
|
|
Log.Information("Получение обновлений успешно началось.");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error($"Ошибка при запуске получения обновлений: {ex.Message}");
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
2025-03-12 22:17:34 +07:00
|
|
|
|
// Создание TaskCompletionSource для удержания процесса бота
|
|
|
|
|
var tcs = new TaskCompletionSource();
|
|
|
|
|
await tcs.Task; // Это заставит бота работать до тех пор, пока не будет отменен
|
|
|
|
|
|
|
|
|
|
// Ожидаем отмены через token
|
|
|
|
|
cts.Token.WaitHandle.WaitOne();
|
2025-03-12 17:52:00 +07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
|
|
|
|
{
|
2025-03-12 22:41:14 +07:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (update.Type != UpdateType.Message || update.Message?.Text == null)
|
|
|
|
|
return;
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
2025-03-12 22:41:14 +07:00
|
|
|
|
var message = update.Message;
|
|
|
|
|
Log.Information($"Получено сообщение от {message.Chat.Id}: {message.Text}");
|
2025-03-12 17:52:00 +07:00
|
|
|
|
|
2025-03-12 22:41:14 +07:00
|
|
|
|
if (message.Text == "/start")
|
|
|
|
|
{
|
2025-03-17 15:33:06 +07:00
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Привет! Я бот для сбора заявок на ремонт оборудования. Отправь /report для подачи заявки.");
|
2025-03-17 15:07:41 +07:00
|
|
|
|
Log.Information($"Ответ на команду /start отправлен.");
|
2025-03-12 22:41:14 +07:00
|
|
|
|
}
|
|
|
|
|
else if (message.Text == "/report")
|
|
|
|
|
{
|
2025-03-17 14:53:01 +07:00
|
|
|
|
usersWaitingForReport[message.Chat.Id] = true; // Отметить, что пользователь должен отправить описание
|
2025-03-17 15:33:06 +07:00
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Пожалуйста, отправьте описание проблемы.");
|
2025-03-12 22:41:14 +07:00
|
|
|
|
Log.Information("Ответ на команду /report отправлен.");
|
|
|
|
|
}
|
2025-03-17 15:35:56 +07:00
|
|
|
|
else if (message.Text.StartsWith("/admin"))
|
2025-03-17 15:33:06 +07:00
|
|
|
|
{
|
|
|
|
|
string passwordAttempt = message.Text.Substring(7); // Получаем пароль, который ввел пользователь
|
|
|
|
|
|
|
|
|
|
if (passwordAttempt == adminPassword)
|
|
|
|
|
{
|
|
|
|
|
admins.Add(message.Chat.Id); // Назначаем пользователя администратором
|
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Вы стали администратором.");
|
|
|
|
|
Log.Information($"Пользователь {message.Chat.Id} стал администратором.");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Неверный пароль.");
|
|
|
|
|
Log.Information($"Неудачная попытка входа для пользователя {message.Chat.Id}.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (admins.Contains(message.Chat.Id)) // Команды доступны только для администраторов
|
|
|
|
|
{
|
|
|
|
|
if (message.Text == "/view_reports")
|
|
|
|
|
{
|
|
|
|
|
await ViewReports(botClient, message.Chat.Id);
|
|
|
|
|
}
|
|
|
|
|
else if (message.Text.StartsWith("/change_status "))
|
|
|
|
|
{
|
|
|
|
|
string[] parts = message.Text.Split(' ', 3);
|
|
|
|
|
if (parts.Length >= 3)
|
|
|
|
|
{
|
|
|
|
|
long reportId = long.Parse(parts[1]);
|
|
|
|
|
string newStatus = parts[2];
|
|
|
|
|
await ChangeReportStatus(reportId, newStatus);
|
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Статус заявки изменен.");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Неверный формат команды. Используйте /change_status <Id> <новый статус>.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-17 14:53:01 +07:00
|
|
|
|
else if (usersWaitingForReport.ContainsKey(message.Chat.Id) && usersWaitingForReport[message.Chat.Id])
|
|
|
|
|
{
|
|
|
|
|
string problemDescription = message.Text;
|
|
|
|
|
await SaveReportToDatabase(message.Chat.Id, problemDescription);
|
2025-03-17 15:33:06 +07:00
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Спасибо за заявку! Мы обработаем её в ближайшее время.");
|
2025-03-17 14:53:01 +07:00
|
|
|
|
usersWaitingForReport[message.Chat.Id] = false;
|
2025-03-17 15:33:06 +07:00
|
|
|
|
Log.Information($"Заявка пользователя {message.Chat.Id} сохранена в базе данных.");
|
2025-03-17 14:53:01 +07:00
|
|
|
|
}
|
2025-03-12 22:41:14 +07:00
|
|
|
|
else
|
|
|
|
|
{
|
2025-03-17 15:33:06 +07:00
|
|
|
|
await botClient.SendMessage(chatId: message.Chat.Id, text: "Неизвестная команда. Используйте /start.");
|
2025-03-12 22:41:14 +07:00
|
|
|
|
Log.Information("Ответ на неизвестную команду отправлен.");
|
|
|
|
|
}
|
2025-03-12 17:52:00 +07:00
|
|
|
|
}
|
2025-03-12 22:41:14 +07:00
|
|
|
|
catch (Exception ex)
|
2025-03-12 17:52:00 +07:00
|
|
|
|
{
|
2025-03-12 22:41:14 +07:00
|
|
|
|
Log.Error($"Ошибка при обработке обновлений: {ex.Message}");
|
|
|
|
|
Log.Error($"StackTrace: {ex.StackTrace}");
|
2025-03-12 17:52:00 +07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-17 14:53:01 +07:00
|
|
|
|
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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-17 15:07:41 +07:00
|
|
|
|
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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-17 15:33:06 +07:00
|
|
|
|
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 async Task ChangeReportStatus(long reportId, string newStatus)
|
|
|
|
|
{
|
|
|
|
|
string connectionString = "Data Source=bot.db";
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (var connection = new SqliteConnection(connectionString))
|
|
|
|
|
{
|
|
|
|
|
await connection.OpenAsync();
|
|
|
|
|
var command = connection.CreateCommand();
|
|
|
|
|
command.CommandText =
|
|
|
|
|
@"
|
|
|
|
|
UPDATE Reports
|
|
|
|
|
SET Status = @Status
|
|
|
|
|
WHERE Id = @Id;
|
|
|
|
|
";
|
|
|
|
|
command.Parameters.AddWithValue("@Status", newStatus);
|
|
|
|
|
command.Parameters.AddWithValue("@Id", reportId);
|
|
|
|
|
|
|
|
|
|
await command.ExecuteNonQueryAsync();
|
|
|
|
|
Log.Information($"Статус заявки с ID {reportId} изменен на {newStatus}.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error($"Ошибка при изменении статуса заявки: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-12 17:52:00 +07:00
|
|
|
|
private static Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
|
|
|
|
|
{
|
2025-03-12 22:41:14 +07:00
|
|
|
|
Log.Error($"Ошибка в процессе работы с ботом: {exception.Message}");
|
2025-03-12 22:35:28 +07:00
|
|
|
|
Log.Error($"StackTrace: {exception.StackTrace}");
|
2025-03-12 17:52:00 +07:00
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
}
|