using System.Text; using System.Text.Json; using Azure.Communication.CallAutomation; using Azure.Storage.Queues; using Coravel.Invocable; using EnotaryoPH.Data; using EnotaryoPH.Data.Entities; using EnotaryoPH.Web.Common.Jobs.Models; namespace EnotaryoPH.Web.Common.Jobs { public class CheckRecordingAvailabilityInvocable : IInvocable { private readonly QueueClient _queueClient; private readonly CallAutomationClient _callAutomationClient; private readonly IConfiguration _configuration; private readonly IServiceScopeFactory _serviceScopeFactory; public CheckRecordingAvailabilityInvocable(QueueClient queueClient, CallAutomationClient callAutomationClient, IConfiguration configuration, IServiceScopeFactory serviceScopeFactory) { _queueClient = queueClient; _callAutomationClient = callAutomationClient; _configuration = configuration; _serviceScopeFactory = serviceScopeFactory; } public async Task Invoke() { var message = await _queueClient.ReceiveMessageAsync(); if (message?.Value == null) { return; } var base64EncodedData = message.Value.Body.ToString(); var base64EncodedBytes = Convert.FromBase64String(base64EncodedData); var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var json = Encoding.UTF8.GetString(base64EncodedBytes); var model = JsonSerializer.Deserialize(json, options); if (model?.Data?.RecordingStorageInfo?.RecordingChunks?.Count > 0) { var dbContext = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService(); model.Data.RecordingStorageInfo.RecordingChunks.ForEach(async chunk => { var path = _configuration.GetValue("VideoRecordingsLocation"); if (!Path.Exists(path)) { Directory.CreateDirectory(path); } var fileName = Path.Combine(path, $"{chunk.DocumentId}-{chunk.Index}.mp4"); if (File.Exists(fileName)) { File.Move(fileName, fileName.Replace(".mp4", $"_{DateTime.UtcNow.ToString("yyyy-MM-dd-HH-mm-dd")}.mp4")); } using var memoryStream = new MemoryStream(); await _callAutomationClient .GetCallRecording().DownloadToAsync(new Uri(chunk.ContentLocation), fileName); var schedule = dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.RecordingID == model.Data.RecordingId); if (schedule != null) { if (schedule.VideoRecording == null) { schedule.VideoRecording = new VideoRecording { CreatedOn = DateTime.UtcNow, LocationType = nameof(VideoRecordingLocationType.LocalFolder), VideoConferenceScheduleID = schedule.LawyerVideoConferenceScheduleID, VideoRecording_UID = Guid.CreateVersion7(DateTime.UtcNow) }; } schedule.VideoRecording.Path = fileName; schedule.VideoRecording.Metadata = JsonSerializer.Serialize(json); dbContext.UpdateOrCreate(schedule); dbContext.SaveChanges(); } }); } await _queueClient.DeleteMessageAsync(message.Value.MessageId, message.Value.PopReceipt); } } }