public async Task <SendHostEmailResponse> EmailHostAsync(string accessCode, Guid sendingUserId) { var codeValidationResult = _validatorLocator.Validate <ProjectAccessCodeValidator>(accessCode); if (!codeValidationResult.IsValid) { throw new ValidationFailedException(codeValidationResult.Errors); } var getUserResponse = (await _userApi.GetBasicUserAsync(sendingUserId)); var sendingUser = getUserResponse.Payload; if (!getUserResponse.IsSuccess()) { if (getUserResponse.ResponseCode == HttpStatusCode.NotFound) { throw new NotFoundException($"User with id {sendingUserId} could not be found"); } throw new InvalidOperationException(); } var userSession = await _guestSessionRepository.CreateItemQuery() .FirstOrDefaultAsync(x => x.UserId == sendingUserId && x.ProjectAccessCode == accessCode); if (userSession == null) { throw new NotFoundException($"User guest session with userId {sendingUserId} and project access code {accessCode} could not be found"); } var project = (await _serviceToServiceProjectApi.GetProjectByAccessCodeAsync(accessCode)).Payload; if (project == null) { throw new NotFoundException($"Project with access code {accessCode} could not be found"); } if (userSession.EmailedHostDateTime != null) { // This is not an error, but a no-op. return(new SendHostEmailResponse { EmailSentDateTime = userSession.EmailedHostDateTime.Value, SentBy = sendingUser.Email }); } var invite = await _guestInviteRepository.CreateItemQuery() .FirstOrDefaultAsync(x => x.UserId == sendingUserId && x.ProjectAccessCode == accessCode); var hostUser = invite == null ? (await _userApi.GetBasicUserAsync(project.OwnerId)).Payload : (await _userApi.GetBasicUserAsync(invite.InvitedBy)).Payload ?? (await _userApi.GetBasicUserAsync(project.OwnerId)).Payload; if (hostUser == null) { throw new InvalidOperationException($"Unable to find a host user for guest principal {sendingUserId} using access code {accessCode}"); } var response = await _emailSendingService.SendNotifyHostEmailAsync(hostUser.Email, project.ProjectUri, project.Name, sendingUser.FullName, sendingUser.Email, sendingUser.FirstName); if (!response.IsSuccess()) { throw new SendEmailException($"Notify host email could not be sent - {response.ResponseCode}, {response.ReasonPhrase}"); } userSession.EmailedHostDateTime = DateTime.UtcNow; await _guestSessionRepository.UpdateItemAsync(userSession.Id, userSession); return(new SendHostEmailResponse() { EmailSentDateTime = DateTime.UtcNow, SentBy = sendingUser.Email }); }