diff --git a/Employee.cs b/Employee.cs
index 71046c5..d780807 100644
--- a/Employee.cs
+++ b/Employee.cs
@@ -19,4 +19,4 @@ public class Employee
public string? State { get; set; } // Состояние события (например, "В отпуске")
public DateTime? StartDate { get; set; } // Дата начала события
public DateTime? EndDate { get; set; } // Дата окончания события
-}
\ No newline at end of file
+}
diff --git a/EmployeeContact.cs b/EmployeeContact.cs
index 186dc1a..f6b2dc5 100644
--- a/EmployeeContact.cs
+++ b/EmployeeContact.cs
@@ -3,6 +3,7 @@
public class EmployeeContact
{
public static string GeneralPhoneNumber => "+78123352577";
+
public EmployeeContact(Employee employee)
{
FullName = employee.FullName;
@@ -20,7 +21,9 @@ public class EmployeeContact
Department = employee.Department;
Position = employee.Position;
ExtensionNumber = employee.Phone ?? null; //string.IsNullOrEmpty(employee.Phone) ? null : employee.Phone;
- Phone = string.IsNullOrEmpty(ExtensionNumber) ? GeneralPhoneNumber : $"{GeneralPhoneNumber},{ExtensionNumber}";
+ Phone = string.IsNullOrEmpty(ExtensionNumber)
+ ? GeneralPhoneNumber
+ : $"{GeneralPhoneNumber},{ExtensionNumber}";
if (!string.IsNullOrEmpty(employee.Mobile))
{
Mobile = employee.Mobile;
@@ -34,13 +37,14 @@ public class EmployeeContact
{
get
{
- string text = "BEGIN:VCARD\n"
- + "VERSION:2.1\n"
- + $"N:{LastName};{FirstName}\n"
- + $"FN:{FullName}\n"
- + "ORG:NSSZ\n"
- + $"ROLE:{Department}\n"
- + $"TITLE:{Position}\n";
+ string text =
+ "BEGIN:VCARD\n"
+ + "VERSION:2.1\n"
+ + $"N:{LastName};{FirstName}\n"
+ + $"FN:{FullName}\n"
+ + "ORG:NSSZ\n"
+ + $"ROLE:{Department}\n"
+ + $"TITLE:{Position}\n";
if (!string.IsNullOrEmpty(Mobile))
text += $"TEL;CELL:{Mobile}\n";
diff --git a/FavoriteContactsManager.cs b/FavoriteContactsManager.cs
new file mode 100644
index 0000000..1e8cf44
--- /dev/null
+++ b/FavoriteContactsManager.cs
@@ -0,0 +1,56 @@
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace nsszcontactbot;
+public class FavoriteContactsManager
+{
+ private readonly IDatabase _redisDb;
+ private const string KeyPrefix = "user:favorites:";
+
+ public FavoriteContactsManager(ConnectionMultiplexer redis)
+ {
+ _redisDb = redis.GetDatabase();
+ }
+
+ ///
+ /// Добавить контакт в избранное.
+ ///
+ public async Task AddFavoriteAsync(long userId, string contactId)
+ {
+ string key = GetRedisKey(userId);
+ await _redisDb.SetAddAsync(key, contactId);
+ }
+
+ ///
+ /// Удалить контакт из избранного.
+ ///
+ public async Task RemoveFavoriteAsync(long userId, string contactId)
+ {
+ string key = GetRedisKey(userId);
+ await _redisDb.SetRemoveAsync(key, contactId);
+ }
+
+ ///
+ /// Проверить, является ли контакт избранным.
+ ///
+ public async Task IsFavoriteAsync(long userId, string contactId)
+ {
+ string key = GetRedisKey(userId);
+ return await _redisDb.SetContainsAsync(key, contactId);
+ }
+
+ ///
+ /// Получить список всех избранных контактов пользователя.
+ ///
+ public async Task> GetAllFavoritesAsync(long userId)
+ {
+ string key = GetRedisKey(userId);
+ var members = await _redisDb.SetMembersAsync(key);
+ return members.Select(m => m.ToString()).ToList();
+ }
+
+ private string GetRedisKey(long userId) => $"{KeyPrefix}{userId}";
+}
diff --git a/InlineKeyboardMarkupExtensions.cs b/InlineKeyboardMarkupExtensions.cs
new file mode 100644
index 0000000..75ad520
--- /dev/null
+++ b/InlineKeyboardMarkupExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types.ReplyMarkups;
+
+namespace nsszcontactbot
+{
+ internal static class InlineKeyboardMarkupExtensions
+ {
+ internal static InlineKeyboardMarkup AddCloseButton(this InlineKeyboardMarkup markup, bool newRow = true)
+ {
+ var buttonRow = newRow ? markup.AddNewRow() : markup;
+ return buttonRow.AddButton("❌ Закрыть", "close");
+ }
+ }
+}
diff --git a/Program.cs b/Program.cs
index ee3c3f6..78c0219 100644
--- a/Program.cs
+++ b/Program.cs
@@ -4,6 +4,16 @@ using Telegram.Bot.Polling;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using Telegram.Bot.Types.ReplyMarkups;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Serilog;
+using System.Timers;
+using Serilog.Core;
+using NRedisStack;
+using NRedisStack.RedisStackCommands;
+
+using Timer = System.Timers.Timer;
+using StackExchange.Redis;
namespace nsszcontactbot;
@@ -12,48 +22,87 @@ public class Program
private static ITelegramBotClient Bot;
private static List Employees = new();
private static List Departments = new();
- private static int CurrentPage = 0; // Текущая страница для пагинации
- private static int PageSize = 5; // Количество подразделений на странице
+ private static IConfigurationRoot config;
+ private static FavoriteContactsManager FavoritesManager;
+ //private static ILogger Logger;
- public static async Task Main(string[] args)
+ public static async Task Main(string[] args)
{
- Bot = new TelegramBotClient("6237449447:AAEGMmpx-1hUEApFZZS_ySAMZErseKJ8dHo"); // Укажите ваш токен
+ config = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json")
+ .Build();
+
+ Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(config).CreateLogger();
+
+ var botToken = config["Telegram:BotToken"];
+ if (botToken == null)
+ {
+ Log.Error("Токен Telegram-бота не указан в конфигурации.");
+ return 1;
+ }
+
+ ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(config["Redis:Configuration"]!, (conf) =>
+ {
+ conf.User = config["Redis:User"];
+ conf.Password = config["Redis:Password"];
+ });
+
+ FavoritesManager = new FavoriteContactsManager(redis);
+ Bot = new TelegramBotClient(botToken);
List cmds = new();
- await Bot.SetMyCommandsAsync(cmds);
- LoadEmployees();
- var me = await Bot.GetMeAsync();
- Console.WriteLine($"Бот запущен: @{me.Username}");
+ await Bot.SetMyCommands(cmds);
+ if(!LoadEmployees())
+ {
+ return 1;
+ }
+ StartUpdatingEmployeesData();
+
+ var me = await Bot.GetMe();
+
+ Log.Information($"Бот запущен: @{me.Username}");
// Запуск обработки обновлений
var cancellationToken = new CancellationTokenSource().Token;
ReceiverOptions receiverOptions =
- new()
- {
- AllowedUpdates = Array.Empty() // receive all update types except ChatMember related updates
- };
- Bot.StartReceiving(HandleUpdateAsync, HandleErrorAsync, receiverOptions: receiverOptions, cancellationToken: cancellationToken);
+ new()
+ {
+ AllowedUpdates = Array.Empty() // receive all update types except ChatMember related updates
+ };
+ Bot.StartReceiving(
+ HandleUpdateAsync,
+ HandleErrorAsync,
+ receiverOptions: receiverOptions,
+ cancellationToken: cancellationToken
+ );
Console.WriteLine("Нажмите Enter для выхода...");
Console.ReadLine();
+ return 0;
}
- private static async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
+ private static async Task HandleUpdateAsync(
+ ITelegramBotClient botClient,
+ Update update,
+ CancellationToken cancellationToken
+ )
{
if (update.Type == UpdateType.Message && update.Message?.Text != null)
{
var message = update.Message;
+ Log.Debug($"INPUT: from={message.From?.Username} text={message.Text}");
if (message.Text.StartsWith("/start"))
{
await StartCommand(message);
}
- else if (message.Text.StartsWith("/choose_department"))
+ else if (message.Text.EndsWith("Список подразделений"))
{
await ChooseDepartment(message);
}
- else if (message.ReplyToMessage != null && message.ReplyToMessage.Text!.StartsWith("Выберите подразделение"))
+ else if (message.Text.EndsWith("Избранные контакты"))
{
- await HandleDepartmentSelection(message);
+ await HandleShowFavorites(message);
}
else
{
@@ -74,57 +123,82 @@ public class Program
await HandleAddContact(update.CallbackQuery, dataParts[1]);
break;
}
+
+ case "addfavorite":
+ {
+ if (dataParts.Length != 2)
+ break;
+ await HandleAddFavorite(update.CallbackQuery, dataParts[1]);
+ break;
+ }
+
+ case "delfavorite":
+ {
+ if (dataParts.Length != 2)
+ break;
+ await HandleDelFavorite(update.CallbackQuery, dataParts[1]);
+ break;
+ }
+
+ case "showdepartment":
+ {
+ if (dataParts.Length != 2)
+ break;
+ await HandleShowDepartment(update.CallbackQuery, int.Parse(dataParts[1]));
+ break;
+ }
+
+ case "showemployee":
+ {
+ if (dataParts.Length != 2)
+ break;
+ await HandleShowEmployee(update.CallbackQuery, dataParts[1]);
+ break;
+ }
+
+ case "close":
+ {
+ await HandleClose(
+ update.CallbackQuery,
+ dataParts.Length > 1 ? dataParts[1] : null
+ );
+ break;
+ }
+
default:
break;
}
}
-
}
}
private static async Task StartCommand(Message message)
{
- string text = "Привет! Я бот для поиска контактов сотрудников. Введите запрос.\n";
- //text += "/choose_department - Выбрать подразделение\n";
- await Bot.SendTextMessageAsync(message.Chat.Id, text);
+ string text = "Привет! Я бот для поиска контактов сотрудников. Введите критерии поиска или воспользуйтесь кнопками внизу.\n";
+ await Bot.SendMessage(message.Chat.Id, text, replyMarkup: new string[] { "⭐️ Избранные контакты", "🏢 Список подразделений" });
}
private static async Task ChooseDepartment(Message message)
{
Departments = Employees.Select(e => e.Department).Distinct().ToList();
- CurrentPage = 0; // Сброс страницы
await ShowDepartments(message.Chat.Id);
}
private static async Task ShowDepartments(long chatId)
{
- var totalDepartments = Departments.Count;
- var totalPages = (int)Math.Ceiling((double)totalDepartments / PageSize);
- var departmentsToShow = Departments.Skip(CurrentPage * PageSize).Take(PageSize).ToList();
+ string text = "Выберите подразделение:";
+ var keyboardMarkup = new InlineKeyboardMarkup();
- string text = "Выберите подразделение:\n";
- text += string.Join("\n", departmentsToShow.Select((d, i) => $"{i + 1 + CurrentPage * PageSize}. {d}"));
-
- // Создание кнопок
- var inlineKeyboard = new List>();
- if (CurrentPage > 0)
+ var departmentIndex = 0;
+ foreach (var department in Departments)
{
- inlineKeyboard.Add(new List
- {
- InlineKeyboardButton.WithCallbackData("◀️ Назад", "prev")
- });
+ keyboardMarkup
+ .AddNewRow()
+ .AddButton($"{department}", $"showdepartment/{departmentIndex++}");
}
- if (CurrentPage < totalPages - 1)
- {
- inlineKeyboard.Add(new List
- {
- InlineKeyboardButton.WithCallbackData("Вперед ▶️", "next")
- });
- }
-
- var keyboardMarkup = new InlineKeyboardMarkup(inlineKeyboard);
-
- await Bot.SendTextMessageAsync(chatId, text, replyMarkup: keyboardMarkup);
+ //keyboardMarkup.AddCloseButton();
+ await Bot.SendMessage(chatId, text, replyMarkup: keyboardMarkup);
+ await Task.Delay(999);
}
private static async Task HandleSearchInput(Message message)
@@ -132,23 +206,48 @@ public class Program
if (!string.IsNullOrEmpty(message.Text))
{
string query = message.Text.Trim().ToLower();
- if (query.Length < 3)
+ if (query.Length < 4)
{
- await Bot.SendTextMessageAsync(message.Chat.Id, "Минимальная длина строки поиска - 3 символа.");
+ await Bot.SendMessage(
+ message.Chat.Id,
+ "Минимальная длина строки поиска - 4 символа."
+ );
return;
}
// Поиск сотрудников по полям
- var results = Employees.Where(e =>
- e.FullName.ToLower().Contains(query) ||
- (e.Mail != null && e.Mail.ToLower().Contains(query)) ||
- (e.Phone != null && e.Phone.Contains(query)) ||
- (e.Mobile != null && e.Mobile.Contains(query)) ||
- (e.IP != null && e.IP.Contains(query))
- ).OrderBy(e => e.FullName.ToLower().IndexOf(query)).ToList();
+ var results = Employees
+ .Where(
+ e =>
+ e.FullName.ToLower().Contains(query)
+ || (e.Mail != null && e.Mail.ToLower().Contains(query))
+ || (e.Phone != null && e.Phone.Contains(query))
+ || (e.Mobile != null && e.Mobile.Contains(query))
+ || (e.IP != null && e.IP.Contains(query))
+ )
+ .OrderBy(e => e.FullName.ToLower().IndexOf(query))
+ .ToList();
// Отправка результатов поиска
- await ShowEmployeeResults(message.Chat.Id, results);
+ await ShowEmployeeResults(message, results, null);
+ }
+ }
+
+ private static async Task HandleShowFavorites(Message message)
+ {
+ if (!string.IsNullOrEmpty(message.Text))
+ {
+ var ids = await FavoritesManager.GetAllFavoritesAsync(message.From.Id);
+ // Поиск сотрудников по полям
+ var results = Employees
+ .Where(
+ e => ids.Contains(e.Id)
+ )
+ .OrderBy(e => e.FullName)
+ .ToList();
+
+ // Отправка результатов поиска
+ await ShowEmployeeResults(message, results, true);
}
}
@@ -160,79 +259,223 @@ public class Program
if (employee != null)
{
EmployeeContact contact = new(employee);
- string phoneNumber = !string.IsNullOrEmpty(contact.Mobile) ? contact.Mobile : contact.Phone;
- var replyParameters = new ReplyParameters() { MessageId = callbackQuery.Message.MessageId, QuoteParseMode = ParseMode.Html, Quote = $"{contact.FullName}" };
- await Bot.SendContactAsync(callbackQuery.Message.Chat.Id, phoneNumber, contact.FirstName, lastName: contact.LastName, vcard: contact.VCard, replyParameters: replyParameters);
+ string phoneNumber = !string.IsNullOrEmpty(contact.Mobile)
+ ? contact.Mobile
+ : contact.Phone;
+ var replyParameters = new ReplyParameters()
+ {
+ MessageId = callbackQuery.Message.MessageId,
+ QuoteParseMode = ParseMode.Html,
+ Quote = $"{contact.FullName}"
+ };
+ var keyboardMarkup = new InlineKeyboardMarkup()
+ //.AddNewRow()
+ .AddCloseButton();
+ await Bot.SendContact(
+ callbackQuery.Message.Chat.Id,
+ phoneNumber,
+ contact.FirstName,
+ lastName: contact.LastName,
+ vcard: contact.VCard,
+ replyParameters: replyParameters,
+ replyMarkup: keyboardMarkup,
+ protectContent: true
+ );
await Task.Delay(999);
}
}
- await Bot.AnswerCallbackQueryAsync(callbackQuery.Id);
+ await Bot.AnswerCallbackQuery(callbackQuery.Id);
}
- private static async Task HandleDepartmentSelection(Message message)
+ private static async Task HandleAddFavorite(CallbackQuery callbackQuery, string contactId)
{
- if (message.Text.StartsWith("◀️ Назад"))
+ if (callbackQuery.Message != null)
{
- if (CurrentPage > 0)
+ var employee = Employees.Where(e => e.Id == contactId).First();
+ if (employee != null)
{
- CurrentPage--;
- await ShowDepartments(message.Chat.Id);
- }
- }
- else if (message.Text.StartsWith("Вперед ▶️"))
- {
- CurrentPage++;
- await ShowDepartments(message.Chat.Id);
- }
- else
- {
- int selectedIndex = int.Parse(message.Text) - 1;
- if (selectedIndex >= 0 && selectedIndex < Departments.Count)
- {
- string selectedDepartment = Departments[selectedIndex];
- var results = Employees.Where(e => e.Department == selectedDepartment).ToList();
- await ShowEmployeeResults(message.Chat.Id, results);
- }
- else
- {
- await Bot.SendTextMessageAsync(message.Chat.Id, "Некорректный выбор.");
+ await FavoritesManager.AddFavoriteAsync(callbackQuery.From.Id, contactId);
+ foreach (var row in callbackQuery.Message.ReplyMarkup.InlineKeyboard)
+ foreach (var cell in row)
+ {
+ if (cell.CallbackData.Contains("addfavorite"))
+ {
+ cell.CallbackData = $"delfavorite/{contactId}";
+ cell.Text = "💔 Не избранный";
+ }
+
+ }
+ await Bot.EditMessageReplyMarkup(callbackQuery.Message.Chat.Id, callbackQuery.Message.MessageId, callbackQuery.Message.ReplyMarkup);
+ await Bot.AnswerCallbackQuery(callbackQuery.Id, "✔️ Контакт добавлен в избранные");
}
}
}
- private static async Task ShowEmployeeResults(long chatId, List results)
+ private static async Task HandleDelFavorite(CallbackQuery callbackQuery, string contactId)
+ {
+ if (callbackQuery.Message != null)
+ {
+ var employee = Employees.Where(e => e.Id == contactId).First();
+ if (employee != null)
+ {
+ await FavoritesManager.RemoveFavoriteAsync(callbackQuery.From.Id, contactId);
+ foreach (var row in callbackQuery.Message.ReplyMarkup.InlineKeyboard)
+ foreach (var cell in row)
+ {
+ if (cell.CallbackData.Contains("delfavorite"))
+ {
+ cell.CallbackData = $"addfavorite/{contactId}";
+ cell.Text = "❤️ В избранные";
+ }
+
+ }
+ await Bot.EditMessageReplyMarkup(callbackQuery.Message.Chat.Id, callbackQuery.Message.MessageId, callbackQuery.Message.ReplyMarkup);
+ await Bot.AnswerCallbackQuery(callbackQuery.Id, "✔️ Контакт удален из избранных");
+ }
+ }
+ }
+
+ private static async Task HandleShowDepartment(CallbackQuery callbackQuery, int departmentIndex)
+ {
+ await Bot.AnswerCallbackQuery(callbackQuery.Id);
+ if (callbackQuery.Message != null)
+ {
+ await Bot.DeleteMessage(
+ callbackQuery.Message.Chat.Id,
+ callbackQuery.Message.MessageId
+ );
+
+ var employees = Employees
+ .Where(e => e.Department == Departments[departmentIndex])
+ .OrderBy(e => e.FullName)
+ .ToList();
+ if (employees != null)
+ {
+ await ShowEmployeeResults(callbackQuery.Message, employees, null);
+ }
+ }
+ //await Bot.AnswerCallbackQueryAsync(callbackQuery.Id);
+ }
+
+ private static async Task HandleShowEmployee(CallbackQuery callbackQuery, string id)
+ {
+ if (callbackQuery.Message != null)
+ {
+ var employee = Employees.Where(e => e.Id == id).First();
+ if (employee != null)
+ {
+ var isFavorite = await FavoritesManager.IsFavoriteAsync(callbackQuery.From.Id, id);
+ await ShowEmployeeCard(callbackQuery.Message.Chat.Id, employee, isFavorite, closeButton: true);
+ }
+ }
+ await Bot.AnswerCallbackQuery(callbackQuery.Id);
+ }
+
+
+ private static async Task HandleClose(CallbackQuery callbackQuery, string? nextAction)
+ {
+ if (callbackQuery.Message != null)
+ {
+ await Bot.DeleteMessage(
+ callbackQuery.Message.Chat.Id,
+ callbackQuery.Message.MessageId
+ );
+ await Task.Delay(500);
+ }
+ await Bot.AnswerCallbackQuery(callbackQuery.Id);
+ }
+
+ private static async Task ShowEmployeeCard(long chatId, Employee employee, bool isFavorite = false, bool contactButton = true, bool favoriteButton = true, bool closeButton = false)
+ {
+ {
+ var keyboardMarkup = new InlineKeyboardMarkup();
+ var keyboardRow = keyboardMarkup.AddNewRow();
+ if (contactButton)
+ keyboardRow.AddButton("👤 Контакт", $"addcontact/{employee.Id}");
+
+ if (favoriteButton)
+ {
+ if (isFavorite)
+ {
+ keyboardRow.AddButton("💔 Не избранный", $"delfavorite/{employee.Id}");
+ }
+ else
+ {
+ keyboardRow.AddButton("❤️ В избранные", $"addfavorite/{employee.Id}");
+ }
+ }
+
+ if (closeButton)
+ keyboardRow.AddCloseButton();
+
+ var card = CreateEmployeeCard(employee);
+
+ string photoPath = Path.Combine(config["Paths:PhotoBasePath"]!, $"{employee.FullName}.jpg");
+ try
+ {
+ await using var fileStream = new FileStream(
+ photoPath,
+ FileMode.Open,
+ FileAccess.Read
+ );
+
+ await Bot.SendPhoto(
+ chatId,
+ fileStream,
+ caption: card,
+ parseMode: ParseMode.Html,
+ replyMarkup: keyboardMarkup
+ );
+ }
+ catch (FileNotFoundException)
+ {
+ await Bot.SendMessage(
+ chatId,
+ card,
+ ParseMode.Html,
+ replyMarkup: keyboardMarkup,
+ protectContent: true
+ );
+ }
+ finally
+ {
+ await Task.Delay(999);
+ }
+ }
+ }
+
+ private static async Task ShowEmployeeResults(Message message, List results, bool? isFavorite = false)
{
if (results.Any())
{
- foreach (var employee in results)
+ if (results.Count < 10)
{
- var keyboardMarkup = new InlineKeyboardMarkup()
- //.AddNewRow("1.1", "1.2", "1.3")
- .AddNewRow()
- .AddButton("👤 Контакт", $"addcontact/{employee.Id}");
- //.AddButton("В избранные", $"addfavorite/{employee.Id}");
- //.AddButton(InlineKeyboardButton.WithUrl("Написать письмо", $"mailto:{employee.Mail}"));
+ foreach (var employee in results)
+ {
+ bool bFavorite = isFavorite.HasValue ? isFavorite == true : await FavoritesManager.IsFavoriteAsync(message.From.Id, employee.Id);
+ await ShowEmployeeCard(message.Chat.Id, employee, bFavorite);
+ }
+ }
+ else
+ {
+ string text = "Вот, что удалось найти:";
+ var keyboardMarkup = new InlineKeyboardMarkup();
- var card = CreateEmployeeCard(employee);
- string photoPath = $"data/photos/{employee.FullName}.jpg";
- try
+ foreach (var employee in results)
{
- await using var fileStream = new FileStream(photoPath, FileMode.Open, FileAccess.Read);
- await Bot.SendPhotoAsync(chatId, fileStream, caption: card, parseMode: ParseMode.Html, replyMarkup: keyboardMarkup);
- }
- catch (FileNotFoundException)
- {
- await Bot.SendTextMessageAsync(chatId, card, null, ParseMode.Html, replyMarkup: keyboardMarkup);
- }
- finally
- {
- await Task.Delay(999);
+ keyboardMarkup
+ .AddNewRow()
+ .AddButton(employee.FullName, $"showemployee/{employee.Id}");
}
+
+ await Bot.SendMessage(message.Chat.Id, text, replyMarkup: keyboardMarkup, protectContent: true);
+ await Task.Delay(999);
}
}
else
{
- await Bot.SendTextMessageAsync(chatId, "Сотрудники не найдены.");
+ await Bot.SendMessage(message.Chat.Id, "🔍 Извините, мы ничего не нашли.");
+ await Task.Delay(999);
}
}
@@ -263,9 +506,10 @@ public class Program
private static string CreateEmployeeCard(Employee employee)
{
EmployeeContact contact = new(employee);
- string card = $"👤 {contact.FullName}\n" +
- $"🏢 {contact.Department}\n" +
- $"🎓 {contact.Position}\n";
+ string card =
+ $"👤 {contact.FullName}\n"
+ + $"🏢 {contact.Department}\n"
+ + $"🎓 {contact.Position}\n";
if (!string.IsNullOrEmpty(contact.Mail))
card += $"✉️ {contact.Mail}\n";
@@ -275,8 +519,8 @@ public class Program
if (!string.IsNullOrEmpty(contact.ExtensionNumber))
card += $"📞 {contact.ExtensionNumber}\n";
- //if (!string.IsNullOrEmpty(employee.IP))
- // card += $"🌐 {employee.IP}\n";
+ if (!string.IsNullOrEmpty(employee.IP))
+ card += $"🌐 {employee.IP}\n";
card += GetEventStatus(employee);
@@ -285,12 +529,14 @@ public class Program
private static string CreateEmployeeCard2(Employee employee)
{
- string photoUrl = $"https://contacts.int.nssz.ru/data/photos/{employee.FullName.Replace(" ", "%20")}.jpg"; // Формирование пути к фотографии
+ string photoUrl =
+ $"https://contacts.int.nssz.ru/data/photos/{employee.FullName.Replace(" ", "%20")}.jpg"; // Формирование пути к фотографии
- string card = $"👤 {employee.FullName}\n" +
- $"🏢 Отдел: {employee.Department}\n" +
- $"🎓 Должность: {employee.Position}\n" +
- $"📸 Фото: Посмотреть фото\n"; // Добавление ссылки на фото
+ string card =
+ $"👤 {employee.FullName}\n"
+ + $"🏢 Отдел: {employee.Department}\n"
+ + $"🎓 Должность: {employee.Position}\n"
+ + $"📸 Фото: Посмотреть фото\n"; // Добавление ссылки на фото
if (!string.IsNullOrEmpty(employee.Mail))
card += $"✉️ Почта: {employee.Mail}\n";
@@ -306,16 +552,50 @@ public class Program
return card;
}
- private static void LoadEmployees()
+ private static Timer? updateTimer = null;
+ private static void StartUpdatingEmployeesData(int intervalMs = 1 * 60 * 60 * 1000)
{
- // Загрузка данных сотрудников из JSON файла
- var json = System.IO.File.ReadAllText("data/contacts.json");
- Employees = JsonConvert.DeserializeObject>(json)!;
+ if (updateTimer != null) return;
+ updateTimer = new Timer(intervalMs);
+ updateTimer.Elapsed += UpdateTimer_Elapsed;
+ updateTimer.AutoReset = true; // Запускать снова после завершения
+ updateTimer.Enabled = true;
}
- private static Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
+ private static void UpdateTimer_Elapsed(object? sender, ElapsedEventArgs e)
{
- Console.WriteLine($"Произошла ошибка: {exception.Message}");
+ LoadEmployees();
+ }
+
+ private static int prevHash = 0;
+ private static bool LoadEmployees()
+ {
+ try
+ {
+ // Загрузка данных сотрудников из JSON файла при наличии изменений
+ var json = System.IO.File.ReadAllText(config["Paths:ContactsJsonPath"]!);
+ int newHash = json.GetHashCode();
+ if (prevHash == newHash)
+ {
+ return true;
+ }
+ prevHash = newHash;
+ Employees = JsonConvert.DeserializeObject>(json)!;
+ Log.Information("Загружены данные о {Count} сотрудниках", Employees.Count);
+ return true;
+ } catch (Exception ex) {
+ Log.Error(ex, "Ошибка при загрузке списка сотрудников");
+ return false;
+ }
+ }
+
+ private static Task HandleErrorAsync(
+ ITelegramBotClient botClient,
+ Exception exception,
+ CancellationToken cancellationToken
+ )
+ {
+ Log.Error(exception, "Произошла ошибка");
return Task.CompletedTask;
}
}
diff --git a/appsettings.json b/appsettings.json
new file mode 100644
index 0000000..ce0412f
--- /dev/null
+++ b/appsettings.json
@@ -0,0 +1,28 @@
+{
+ "Paths": {
+ "ContactsJsonPath": "data/contacts.json",
+ "PhotoBasePath": "data/photos"
+ },
+ "Telegram": {
+ "BotToken": "8155021946:AAGbfJnLa0sTWxqFB9yjbXhbTedBw4wvcQE"
+ },
+ "Redis": {
+ "Configuration": "redis-15840.crce198.eu-central-1-3.ec2.redns.redis-cloud.com:15840",
+ "User": "tgbot",
+ "Password": "0aCKMee9Ocq88KzfjWyC9AmB25tLiY93%"
+ },
+ "Serilog": {
+ "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
+ "MinimumLevel": "Debug",
+ "WriteTo": [
+ { "Name": "Console" },
+ {
+ "Name": "File",
+ "Args": {
+ "path": "nsszcontactbot.log",
+ "rollingInterval": "Day"
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/nsszcontactbot.csproj b/nsszcontactbot.csproj
index 49a15d5..10e6652 100644
--- a/nsszcontactbot.csproj
+++ b/nsszcontactbot.csproj
@@ -7,8 +7,19 @@
enable
+
-
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+