using Microsoft.Extensions.Configuration; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; var basePath = Directory.GetCurrentDirectory(); var configuration = new ConfigurationBuilder() .SetBasePath(basePath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); WriteToConsole("Consumer Start!"); var host = configuration["Rabbit:Host"] ?? ""; var user = configuration["Rabbit:User"] ?? ""; var pass = configuration["Rabbit:Password"] ?? ""; var queue = configuration["Rabbit:Queue"] ?? "basic-queue"; // create connection var factory = new ConnectionFactory() { HostName = host, UserName = user, Password = pass }; using var connection = factory.CreateConnection(); using var channel = connection.CreateModel(); channel.QueueDeclare(queue: queue, durable: true, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); string? consumerTag = null; bool isConsuming = false; consumer.Received += async (model, ea) => { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); // Double-check time before processing (safety check) if (!IsWithinOperatingHours()) { WriteToConsole($"Message received outside operating hours. Requeuing message."); channel.BasicNack(ea.DeliveryTag, false, true); // Requeue the message return; } await CallRestApi(message); WriteToConsole($"ได้รับคำขอจาก Queue: {message}"); }; // Monitor and control consumer based on time schedule using var timer = new PeriodicTimer(TimeSpan.FromMinutes(1)); while (await timer.WaitForNextTickAsync()) { var shouldBeConsuming = IsWithinOperatingHours(); if (shouldBeConsuming && !isConsuming) { // Start consuming consumerTag = channel.BasicConsume(queue: queue, autoAck: true, consumer: consumer); isConsuming = true; WriteToConsole($"✅ Started consuming messages at {GetCurrentBangkokTime():yyyy-MM-dd HH:mm:ss}"); } else if (!shouldBeConsuming && isConsuming) { // Stop consuming if (consumerTag != null) { channel.BasicCancel(consumerTag); consumerTag = null; } isConsuming = false; WriteToConsole($"⏸️ Stopped consuming messages at {GetCurrentBangkokTime():yyyy-MM-dd HH:mm:ss}. Will resume after 08:10 tomorrow."); } } static void WriteToConsole(string message) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} : {message}"); } async Task CallRestApi(string requestData) { using var client = new HttpClient(); var apiPath = $"{configuration["API"]}/leave/process-check-in"; var content = new StringContent(requestData, Encoding.UTF8, "application/json"); var response = await client.PostAsync(apiPath, content); if (response.IsSuccessStatusCode) { var responseContent = await response.Content.ReadAsStringAsync(); WriteToConsole(responseContent); } else { var errorMessage = await response.Content.ReadAsStringAsync(); var res = JsonSerializer.Deserialize(errorMessage); WriteToConsole($"Error: {res.Message}"); } } DateTime GetCurrentBangkokTime() { var bangkokTimeZone = TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time"); return TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, bangkokTimeZone); } bool IsWithinOperatingHours() { var currentTime = GetCurrentBangkokTime(); var startTime = new TimeSpan(8, 10, 0); // 8:10 AM var endTime = new TimeSpan(23, 59, 59); // End of day var currentTimeOfDay = currentTime.TimeOfDay; // Consumer should only work from 8:10 AM to end of day return currentTimeOfDay >= startTime && currentTimeOfDay <= endTime; } public class ResponseObject { [JsonPropertyName("status")] public int Status { get; set; } [JsonPropertyName("message")] public string? Message { get; set; } [JsonPropertyName("result")] public object? Result { get; set; } } public class CheckTimeDtoRB { public Guid? CheckInId { get; set; } public double Lat { get; set; } = 0; public double Lon { get; set; } = 0; public string POI { get; set; } = string.Empty; public bool IsLocation { get; set; } = true; public string? LocationName { get; set; } = string.Empty; public string? Remark { get; set; } = string.Empty; public Guid? UserId { get; set; } public DateTime? CurrentDate { get; set; } public string? CheckInFileName { get; set; } public byte[]? CheckInFileBytes { get; set; } }