175 lines
8.4 KiB
C#
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;
|
|
}
|
|
}
|
|
} |