using System.Net.Http.Json; using System.Text; using System.Text.Json; using KronaStaffTerminal.Models; namespace KronaStaffTerminal.Services; public sealed class NotificationService { private readonly HttpClient _httpClient = new() { Timeout = TimeSpan.FromSeconds(15) }; public async Task<(bool Delivered, string? Error)> SendAttendanceAsync(TerminalSettings settings, EmployeeRecord employee, string eventType, DateTimeOffset localTime) { var action = eventType.StartsWith("Уход", StringComparison.Ordinal) ? "уход" : "приход"; return await SendAsync(settings, employee, $"Krona Staff: ваш {action} зарегистрирован {localTime:dd.MM.yyyy} в {localTime:HH:mm}."); } public async Task<(bool Delivered, string? Error)> SendTestAsync(TerminalSettings settings, EmployeeRecord employee) { return await SendAsync(settings, employee, "Krona Staff: личные уведомления подключены."); } private async Task<(bool Delivered, string? Error)> SendAsync(TerminalSettings settings, EmployeeRecord employee, string text) { if (employee.IsBlocked) return (false, "Сотрудник заблокирован."); var errors = new List(); var sent = false; var telegramConfigured = settings.TelegramEnabled && !string.IsNullOrWhiteSpace(settings.TelegramBotToken) && !string.IsNullOrWhiteSpace(employee.TelegramChatId); if (telegramConfigured) { try { var url = $"https://api.telegram.org/bot{settings.TelegramBotToken}/sendMessage"; using var response = await _httpClient.PostAsJsonAsync(url, new { chat_id = employee.TelegramChatId, text }); if (!response.IsSuccessStatusCode) { errors.Add($"Telegram: HTTP {(int)response.StatusCode}"); } else { sent = true; } } catch (Exception exception) { errors.Add($"Telegram: {exception.Message}"); } } var vkConfigured = settings.VkEnabled && !string.IsNullOrWhiteSpace(settings.VkGroupToken) && !string.IsNullOrWhiteSpace(employee.VkPeerId); if (vkConfigured) { try { var values = new Dictionary { ["access_token"] = settings.VkGroupToken, ["v"] = "5.199", ["peer_id"] = employee.VkPeerId, ["random_id"] = Random.Shared.Next(1, int.MaxValue).ToString(), ["message"] = text }; using var response = await _httpClient.PostAsync( "https://api.vk.com/method/messages.send", new FormUrlEncodedContent(values)); var responseText = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode || responseText.Contains("\"error\"", StringComparison.OrdinalIgnoreCase)) { errors.Add($"VK: HTTP {(int)response.StatusCode}"); } else { sent = true; } } catch (Exception exception) { errors.Add($"VK: {exception.Message}"); } } var maxConfigured = settings.MaxEnabled && !string.IsNullOrWhiteSpace(settings.MaxBotToken) && !string.IsNullOrWhiteSpace(employee.MaxUserId); if (maxConfigured) { try { var url = $"https://platform-api2.max.ru/messages?user_id={Uri.EscapeDataString(employee.MaxUserId)}"; using var request = new HttpRequestMessage(HttpMethod.Post, url); request.Headers.TryAddWithoutValidation("Authorization", settings.MaxBotToken); request.Content = new StringContent(JsonSerializer.Serialize(new { text }), Encoding.UTF8, "application/json"); using var response = await _httpClient.SendAsync(request); if (!response.IsSuccessStatusCode) { errors.Add($"MAX: HTTP {(int)response.StatusCode}"); } else { sent = true; } } catch (Exception exception) { errors.Add($"MAX: {exception.Message}"); } } if (!telegramConfigured && !vkConfigured && !maxConfigured) { return (false, null); } return (sent && errors.Count == 0, errors.Count == 0 ? null : string.Join("; ", errors)); } }