175 lines
8.4 KiB
C#

using Azure;
using Azure.Communication;
using Azure.Communication.CallAutomation;
using Azure.Communication.Identity;
using Azure.Communication.Rooms;
using EnotaryoPH.Data;
using EnotaryoPH.Data.Entities;
namespace EnotaryoPH.Web.Common.Services
{
public class ConferenceSheduleService : IConferenceSheduleService
{
private readonly NotaryoDBContext _dbContext;
private readonly CommunicationIdentityClient _communicationIdentityClient;
private readonly RoomsClient _roomsClient;
private readonly CallAutomationClient _callAutomationClient;
private readonly IConfiguration _configuration;
public ConferenceSheduleService(NotaryoDBContext dbContext, CommunicationIdentityClient communicationIdentityClient, RoomsClient roomsClient, CallAutomationClient callAutomationClient, IConfiguration configuration)
{
_dbContext = dbContext;
_communicationIdentityClient = communicationIdentityClient;
_roomsClient = roomsClient;
_callAutomationClient = callAutomationClient;
_configuration = configuration;
}
public async Task<Guid> GetOrCreateScheduleIDAsync(Guid transaction_UID)
{
if (transaction_UID == Guid.Empty)
{
return Guid.Empty;
}
var transactionEntity = _dbContext.Transactions
.Include(t => t.TransactionSignatories)
.FirstOrDefault(t => t.Transaction_UID == transaction_UID);
if (transactionEntity == null)
{
return Guid.Empty;
}
var existingSchedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID);
if (existingSchedule != null)
{
return existingSchedule.LawyerVideoConferenceSchedule_UID;
}
var schedule_UID = Guid.Empty;
var isReadyForVideoCall = transactionEntity.TransactionSignatories.All(signatory => signatory.Status == nameof(SignatoryStatus.FaceMatch));
var isAcceptedByLawyer = transactionEntity.Status == nameof(TransactionState.Accepted) && transactionEntity.LawyerID > 0;
if (isReadyForVideoCall && isAcceptedByLawyer)
{
var schedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID);
if (schedule == null)
{
var participants = transactionEntity.TransactionSignatories.ConvertAll(signatory => new LawyerVideoConferenceParticipant
{
CreatedOn = DateTime.UtcNow,
Status = nameof(VideoConferenceStatus.New),
LawyerVideoConferenceParticipant_UID = Guid.CreateVersion7(DateTime.UtcNow),
ParticipantID = signatory.UserID,
});
participants.Add(new LawyerVideoConferenceParticipant
{
CreatedOn = DateTime.UtcNow,
Status = nameof(VideoConferenceStatus.New),
LawyerVideoConferenceParticipant_UID = Guid.CreateVersion7(DateTime.UtcNow),
ParticipantID = transactionEntity.PrincipalID,
});
schedule = new LawyerVideoConferenceSchedule
{
LawyerVideoConferenceSchedule_UID = Guid.CreateVersion7(DateTime.UtcNow),
CreatedOn = DateTime.UtcNow,
LawyerID = transactionEntity.LawyerID.GetValueOrDefault(),
TransactionID = transactionEntity.TransactionID,
MeetingDate = DateTime.UtcNow,
Status = nameof(VideoConferenceStatus.New),
};
var roomParticipants = new List<RoomParticipant>();
foreach (var participant in participants)
{
var attendee = await _communicationIdentityClient.CreateUserAsync();
participant.MeetingRoomTokenID = await GetTokenResponseAsync(attendee);
participant.MeetingRoomUserID = attendee.Value.Id;
roomParticipants.Add(new RoomParticipant(attendee) { Role = ParticipantRole.Attendee });
}
var presenter = await _communicationIdentityClient.CreateUserAsync();
schedule.MeetingRoomTokenID = await GetTokenResponseAsync(presenter);
schedule.MeetingRoomUserID = presenter.Value.Id;
roomParticipants.Add(new RoomParticipant(presenter) { Role = ParticipantRole.Presenter });
CommunicationRoom room = await _roomsClient.CreateRoomAsync(DateTime.Now, DateTime.Now.AddHours(2), roomParticipants);
schedule.MeetingRoomID = room.Id;
schedule.LawyerVideoConferenceParticipants = participants.ToList();
if (schedule.LawyerVideoConferenceScheduleID == 0)
{
_dbContext.Add(schedule);
}
else
{
_dbContext.Update(schedule);
}
_dbContext.SaveChanges();
schedule_UID = schedule.LawyerVideoConferenceSchedule_UID;
}
}
return schedule_UID;
}
public async Task StartRecordingAsync(Guid transaction_UID, string serverCallID)
{
var transactionEntity = _dbContext.Transactions
.FirstOrDefault(t => t.Transaction_UID == transaction_UID) ?? throw new ArgumentException("Transaction not found.");
var existingSchedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID) ?? throw new ArgumentException("Schedule not found.");
if (string.IsNullOrEmpty(existingSchedule.ServerCallID) && string.IsNullOrEmpty(serverCallID))
{
throw new ArgumentException("ServerCallID is not set for this transaction.");
}
if (!string.IsNullOrEmpty(existingSchedule.RecordingID))
{
return;
}
if (!string.IsNullOrEmpty(serverCallID))
{
existingSchedule.ServerCallID = serverCallID;
}
CallLocator callLocator = new ServerCallLocator(existingSchedule.ServerCallID);
var uri = _configuration.GetValue<string>("UriRecordingBloblContainer") ?? string.Empty;
var recordingResult = await _callAutomationClient
.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator)
{
RecordingStorage = RecordingStorage.CreateAzureBlobContainerRecordingStorage(new Uri(uri))
});
existingSchedule.RecordingID = recordingResult.Value.RecordingId;
_dbContext.Update(existingSchedule);
_dbContext.SaveChanges();
}
public async Task StopRecordingAsync(Guid transaction_UID)
{
var transactionEntity = _dbContext.Transactions
.FirstOrDefault(t => t.Transaction_UID == transaction_UID) ?? throw new ArgumentException("Transaction not found.");
var existingSchedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID) ?? throw new ArgumentException("Schedule not found.");
if (string.IsNullOrEmpty(existingSchedule.ServerCallID))
{
throw new ArgumentException("ServerCallID is not set for this transaction.");
}
if (string.IsNullOrEmpty(existingSchedule.RecordingID))
{
throw new ArgumentException("Recording ID is not set for this transaction.");
}
await _callAutomationClient.GetCallRecording().StopAsync(existingSchedule.RecordingID);
}
private async Task<string> GetTokenResponseAsync(Response<CommunicationUserIdentifier> user)
{
var tokenResponse = await _communicationIdentityClient.GetTokenAsync(user, new[] { CommunicationTokenScope.VoIP });
return tokenResponse.Value.Token;
}
}
}