using Azure; using Azure.Communication; using Azure.Communication.Identity; using Azure.Communication.Rooms; using EnotaryoPH.Data; using EnotaryoPH.Data.Entities; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace EnotaryoPH.Web.Pages.Participant.VideoCall { public class RoomModel : PageModel { private const string CONNECTION_STRING = "endpoint=https://comm-enotario.asiapacific.communication.azure.com/;accesskey=yqxq5mRByG8aPwZBiT/KFfx6Rr16RR280dC3GVkGaFVNXGk91sIDy04j5jrZfjDZAvdn0fjtyF0kGJPXMGgfKg=="; private readonly ICurrentUserService _currentUserService; private readonly NotaryoDBContext _dbContext; private readonly ISession _session; private readonly CommunicationUserIdentifier? _user1; private readonly CommunicationUserIdentifier? _user2; private CommunicationIdentityClient? _communicationIdentityClient; private LawyerVideoConferenceSchedule _LawyerVideoConferenceSchedule; private Transaction _Transaction; public RoomModel(IHttpContextAccessor httpContextAccessor, ICurrentUserService currentUserService, NotaryoDBContext dbContext) { _session = httpContextAccessor.HttpContext.Session; _currentUserService = currentUserService; _dbContext = dbContext; } public async Task OnGetAsync() { _Transaction = _dbContext.Transactions .Include(t => t.TransactionSignatories) .FirstOrDefault(t => t.Transaction_UID == Transaction_UID); if (_Transaction == null) { return NotFound(); } _LawyerVideoConferenceSchedule = _dbContext.LawyerVideoConferenceSchedules .Include(meeting => meeting.LawyerVideoConferenceParticipants) .ThenInclude(p => p.Participant) .Include(meeting => meeting.Lawyer) .ThenInclude(l => l.User) .FirstOrDefault(meeting => meeting.TransactionID == _Transaction.TransactionID); if (ShouldCreateRoom()) { _LawyerVideoConferenceSchedule ??= new LawyerVideoConferenceSchedule { LawyerVideoConferenceSchedule_UID = Guid.CreateVersion7(), CreatedOn = DateTime.UtcNow, LawyerID = _Transaction.LawyerID.GetValueOrDefault(), TransactionID = _Transaction.TransactionID, }; _LawyerVideoConferenceSchedule.MeetingDate = DateTime.UtcNow; _LawyerVideoConferenceSchedule.Status = nameof(VideoConferenceStatus.New); var roomParticipants = new List(); foreach (var participant in _LawyerVideoConferenceSchedule.LawyerVideoConferenceParticipants) { var attendee = await CommunicationIdentityClient.CreateUserAsync(); roomParticipants.Add(new RoomParticipant(attendee) { Role = ParticipantRole.Attendee }); participant.MeetingRoomTokenID = await GetTokenResponse(attendee); participant.MeetingRoomUserID = attendee.Value.Id; } var presenter = await CommunicationIdentityClient.CreateUserAsync(); roomParticipants.Add(new RoomParticipant(presenter) { Role = ParticipantRole.Presenter }); _LawyerVideoConferenceSchedule.MeetingRoomTokenID = await GetTokenResponse(presenter); _LawyerVideoConferenceSchedule.MeetingRoomUserID = presenter.Value.Id; var roomsClient = new RoomsClient(CONNECTION_STRING); CommunicationRoom room = await roomsClient.CreateRoomAsync(DateTime.Now, DateTime.Now.AddHours(2), roomParticipants); _LawyerVideoConferenceSchedule.MeetingRoomID = room.Id; if (_LawyerVideoConferenceSchedule.LawyerVideoConferenceScheduleID == 0) { _dbContext.Add(_LawyerVideoConferenceSchedule); } else { _dbContext.Update(_LawyerVideoConferenceSchedule); } _dbContext.SaveChanges(); } var currentUser = _dbContext.Users.FirstOrDefault(u => u.User_UID == _currentUserService.GetUser_UID()); CommunicationUserToken = currentUser.Role == nameof(UserType.Notary) ? _LawyerVideoConferenceSchedule.MeetingRoomTokenID : _LawyerVideoConferenceSchedule.LawyerVideoConferenceParticipants.First(u => u.ParticipantID == currentUser.UserID).MeetingRoomTokenID; CommunicationRoomId = _LawyerVideoConferenceSchedule.MeetingRoomID; CommunicationUserId = currentUser.Role == nameof(UserType.Notary) ? _LawyerVideoConferenceSchedule.MeetingRoomUserID : _LawyerVideoConferenceSchedule.LawyerVideoConferenceParticipants.First(u => u.ParticipantID == currentUser.UserID).MeetingRoomUserID; return Page(); } private static string GetHashCode(string stringValue) => stringValue.GetHashCode().ToString("X8"); private async Task GetTokenResponse(Response user) { var tokenResponse = await CommunicationIdentityClient.GetTokenAsync(user, new[] { CommunicationTokenScope.VoIP }); return tokenResponse.Value.Token; } private bool ShouldCreateRoom() => _LawyerVideoConferenceSchedule == null || DateTime.UtcNow.Subtract(_LawyerVideoConferenceSchedule.MeetingDate).TotalHours > 1 || _LawyerVideoConferenceSchedule.LawyerVideoConferenceParticipants.Any(p => string.IsNullOrEmpty(p.MeetingRoomTokenID)); public string CommunicationRoomId { get; private set; } public string CommunicationUserToken { get; private set; } public string CommunicationUserId { get; set; } public List Participants { get { var signatoryTypes = _Transaction.TransactionSignatories.Where(t => t.UserID > 0).ToDictionary(k => k.UserID, v => v.Type); var dic = _LawyerVideoConferenceSchedule.LawyerVideoConferenceParticipants.ConvertAll(p => new RoomParticipantViewModel { Id = p.LawyerVideoConferenceParticipant_UID.ToString(), DisplayName = $"{p.Participant.Firstname} {p.Participant.Lastname}", RoomUserID = p.MeetingRoomUserID, Type = signatoryTypes.GetValueOrDefault(p.ParticipantID, nameof(UserType.Principal)) }); var host = _LawyerVideoConferenceSchedule.Lawyer.User; dic.Add(new RoomParticipantViewModel { DisplayName = $"{host.Firstname} {host.Lastname}", Id = Guid.Empty.ToString(), RoomUserID = _LawyerVideoConferenceSchedule.MeetingRoomUserID, Type = nameof(UserType.Notary) }); return dic; } } [BindProperty(SupportsGet = true)] public Guid Transaction_UID { get; set; } private CommunicationIdentityClient CommunicationIdentityClient => _communicationIdentityClient ??= new CommunicationIdentityClient(CONNECTION_STRING); } }