public bool CanStartAdhocMeeting(IMessagingInvitation invitation) { #pragma warning disable CS0618 // Type or member is obsolete return(invitation.Supports(MessagingInvitationCapability.StartAdhocMeeting)); #pragma warning restore CS0618 // Type or member is obsolete }
public async Task EstalbishAsyncInviteShouldCompleteOnlyOnCompletedEvent() { TestHelper.RaiseEventsFromFile(m_mockEventChannel, "Event_MessagingDisconnected.json"); // Save OperationId of the MessagingInvitation when HTTP request is made to start the invitation. string operationId = null; m_restfulClient.HandleRequestProcessed += (sender, args) => { if (args.Uri == new Uri(DataUrls.EstablishMessagingCall) && args.Method == HttpMethod.Post && args.Input is InvitationInput) { // We need to replace operationContext in invitation completed event with what was provided in the input operationId = ((InvitationInput)args.Input).OperationContext; } }; // Start MessagingInvitation var inviteCompleted = false; IMessagingInvitation invite = await m_messagingCall.EstablishAsync(m_loggingContext).ConfigureAwait(false); invite.HandleResourceCompleted += (sender, args) => inviteCompleted = true; await Task.Delay(TimeSpan.FromMilliseconds(300)).ConfigureAwait(false); // Make sure invitation is not completed Assert.IsFalse(inviteCompleted); Assert.IsFalse(string.IsNullOrEmpty(operationId)); // When TestHelper.RaiseEventsFromFileWithOperationId(m_mockEventChannel, "Event_MessagingInvitationCompleted.json", operationId); // then Assert.IsTrue(inviteCompleted); }
public async void TestSetup() { m_loggingContext = new LoggingContext(Guid.NewGuid()); var data = TestHelper.CreateApplicationEndpoint(); m_restfulClient = data.RestfulClient; m_eventChannel = data.EventChannel; await data.ApplicationEndpoint.InitializeAsync(m_loggingContext).ConfigureAwait(false); await data.ApplicationEndpoint.InitializeApplicationAsync(m_loggingContext).ConfigureAwait(false); var communication = data.ApplicationEndpoint.Application.Communication; m_restfulClient.HandleRequestProcessed += (sender, args) => { // Deliver invitation started events TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_eventChannel); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.AudioInvitations, HttpMethod.Post, "Event_AudioInvitationStarted.json", m_eventChannel); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.AudioVideoInvitations, HttpMethod.Post, "Event_AudioVideoInvitationStarted.json", m_eventChannel); // Deliver conversation deleted event TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.Conversation, HttpMethod.Delete, "Event_ConversationDeleted.json", m_eventChannel); }; // Start a conversation with messaging modality IMessagingInvitation invitation = await communication .StartMessagingAsync("Test message", new SipUri("sip:[email protected]"), "https://example.com/callback") .ConfigureAwait(false); m_conversation = invitation.RelatedConversation; }
public async Task StartAdhocMeetingShouldReturnATaskToWaitForInvitationStartedEvent() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); var invitationOperationid = string.Empty; m_restfulClient.HandleRequestProcessed += (sender, args) => { string operationId = TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.StartAdhocMeeting, HttpMethod.Post, null, null); if (!string.IsNullOrEmpty(operationId)) { invitationOperationid = operationId; } }; Task invitationTask = m_messagingInvitation.StartAdhocMeetingAsync("Test subject", "https://example.com/callback", m_loggingContext); await Task.Delay(TimeSpan.FromMilliseconds(200)).ConfigureAwait(false); Assert.IsFalse(invitationTask.IsCompleted); // When TestHelper.RaiseEventsFromFileWithOperationId(m_mockEventChannel, "Event_OnlineMeetingInvitationStarted.json", invitationOperationid); // Then Assert.IsTrue(invitationTask.IsCompleted); }
public async void TestSetup() { m_loggingContext = new LoggingContext(Guid.NewGuid()); var data = TestHelper.CreateApplicationEndpoint(); m_mockEventChannel = data.EventChannel; m_restfulClient = data.RestfulClient; ApplicationEndpoint applicationEndpoint = data.ApplicationEndpoint; await applicationEndpoint.InitializeAsync(m_loggingContext).ConfigureAwait(false); await applicationEndpoint.InitializeApplicationAsync(m_loggingContext).ConfigureAwait(false); m_restfulClient.HandleRequestProcessed += (sender, args) => { TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_mockEventChannel); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_ConversationConnected.json", m_mockEventChannel); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_ParticipantAdded.json", m_mockEventChannel); }; IMessagingInvitation invitation = await applicationEndpoint.Application.Communication .StartMessagingAsync("Test subject", new SipUri("sip:[email protected]"), "https://example.com/callback", m_loggingContext) .ConfigureAwait(false); m_conversation = invitation.RelatedConversation; }
public async void TestSetup() { m_loggingContext = new LoggingContext(Guid.NewGuid()); var data = TestHelper.CreateApplicationEndpoint(); m_restfulClient = data.RestfulClient; m_eventChannel = data.EventChannel; await data.ApplicationEndpoint.InitializeAsync(m_loggingContext).ConfigureAwait(false); await data.ApplicationEndpoint.InitializeApplicationAsync(m_loggingContext).ConfigureAwait(false); var communication = data.ApplicationEndpoint.Application.Communication; m_restfulClient.HandleRequestProcessed += (sender, args) => TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_eventChannel); // Start a conversation with messaging modality IMessagingInvitation invitation = await communication .StartMessagingWithIdentityAsync("Test message", "sip:[email protected]", "https://example.com/callback", "Test user 1", "sip:[email protected]") .ConfigureAwait(false); TestHelper.RaiseEventsFromFile(m_eventChannel, "Event_ConversationConferenceAdded.json"); TestHelper.RaiseEventsFromFile(m_eventChannel, "Event_ConversationConferenced.json"); m_conversationConference = invitation.RelatedConversation.ConversationConference; }
public async void TestSetup() { m_loggingContext = new LoggingContext(Guid.NewGuid()); var data = TestHelper.CreateApplicationEndpoint(); m_mockEventChannel = data.EventChannel; m_restfulClient = data.RestfulClient; m_applicationEndpoint = data.ApplicationEndpoint; await m_applicationEndpoint.InitializeAsync(m_loggingContext).ConfigureAwait(false); await m_applicationEndpoint.InitializeApplicationAsync(m_loggingContext).ConfigureAwait(false); ICommunication communication = m_applicationEndpoint.Application.Communication; m_restfulClient.HandleRequestProcessed += (sender, args) => { TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_mockEventChannel); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.EstablishMessagingCall, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_mockEventChannel); }; // Start a messaging invitation m_messagingInvitation = await communication.StartMessagingWithIdentityAsync( "Test subject", "sip:[email protected]", "https://example.com/callback", "Local user", "sip:[email protected]", m_loggingContext); }
public async Task AcceptAndBridgeAsyncShouldWorkWithNullLoggingContext() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); // When await m_messagingInvitation.AcceptAndBridgeAsync(null, "https://example.com", "Example User").ConfigureAwait(false); // Then // No exception is thrown }
public async Task AcceptAndBridgeAsyncShouldMakeHttpRequest() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); // When await m_messagingInvitation.AcceptAndBridgeAsync(m_loggingContext, "https://example.com", "Example User").ConfigureAwait(false); // Then Assert.IsTrue(m_restfulClient.RequestsProcessed("POST " + DataUrls.AcceptAndBridge)); }
public async Task AcceptAndBridgeAsyncShouldThrowIfCapabilityNotAvailable() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall_NoActionLinks.json").ConfigureAwait(false); // When await m_messagingInvitation.AcceptAndBridgeAsync(m_loggingContext, "https://example.com", "Example User").ConfigureAwait(false); // Then // Exception is thrown }
public async Task AcceptAndBridgeAsyncShouldThrowIfMeetingUrlIsWhitespaces() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); // When await m_messagingInvitation.AcceptAndBridgeAsync(m_loggingContext, " ", "Example User").ConfigureAwait(false); // Then // Exception is thrown }
public async Task ShouldSupportStartAdhocMeetingIfLinkAvailable() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); // When bool supported = m_messagingInvitation.Supports(MessagingInvitationCapability.StartAdhocMeeting); // Then Assert.IsTrue(supported); }
public async Task ShouldNotSupportAcceptAndBridgeIfLinkNotAvailable() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall_NoActionLinks.json").ConfigureAwait(false); // When bool supported = m_messagingInvitation.Supports(MessagingInvitationCapability.AcceptAndBridge); // Then Assert.IsFalse(supported); }
public async Task StartAdhocMeetingShouldThrowIfCapabilityNotAvailable() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall_NoActionLinks.json").ConfigureAwait(false); // When await m_messagingInvitation.StartAdhocMeetingAsync("Test subject", "https://example.com/callback", m_loggingContext).ConfigureAwait(false); // Then // Exception is thrown }
public async Task StartAdhocMeetingShouldThrowIfAdhocMeetingStartedEventNotReceived() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); ((MessagingInvitation)m_messagingInvitation).WaitForEvents = TimeSpan.FromMilliseconds(300); // When await m_messagingInvitation.StartAdhocMeetingAsync("Test subject", "https://example.com/callback", m_loggingContext).ConfigureAwait(false); // Then // Exception is thrown }
public async Task StartAdhocMeetingShouldMakeTheHttpRequest() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); m_restfulClient.HandleRequestProcessed += (sender, args) => TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.StartAdhocMeeting, HttpMethod.Post, "Event_OnlineMeetingInvitationStarted.json", m_mockEventChannel); // When await m_messagingInvitation.StartAdhocMeetingAsync("Test subject", "https://example.com/callback", m_loggingContext).ConfigureAwait(false); // Then Assert.IsTrue(m_restfulClient.RequestsProcessed("POST " + DataUrls.StartAdhocMeeting)); }
public async Task StartAdhocMeetingShouldWorkWithNullLoggingContext() { // Given m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); m_restfulClient.HandleRequestProcessed += (sender, args) => TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.StartAdhocMeeting, HttpMethod.Post, "Event_OnlineMeetingInvitationStarted.json", m_mockEventChannel); // When await m_messagingInvitation.StartAdhocMeetingAsync("Test subject", "https://example.com/callback", null).ConfigureAwait(false); // Then // No exception is thrown }
public async Task StartMessagingWithIdentityShouldWork() { // Given // If ClientModel starts a MessagingInvitation, delive the corresponding invitation started event. m_restfulClient.HandleRequestProcessed += (sender, args) => { TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_eventChannel); }; // When IMessagingInvitation invitation = await m_communication .StartMessagingWithIdentityAsync("Test message", "sip:[email protected]", "https://example.com/callback", "Test user 1", "sip:[email protected]") .ConfigureAwait(false); // Then Assert.IsNotNull(invitation); Assert.IsNotNull(invitation.RelatedConversation); Assert.IsTrue(m_restfulClient.RequestsProcessed("POST " + DataUrls.MessagingInvitations)); }
public async Task StartMessagingShouldWork() { // Given m_restfulClient.OverrideResponse(new Uri(DataUrls.Communication), HttpMethod.Get, HttpStatusCode.OK, "Communication_WithStartMessaging.json"); await m_communication.RefreshAsync(m_loggingContext).ConfigureAwait(false); // If ClientModel starts a MessagingInvitation, delive the corresponding invitation started event. m_restfulClient.HandleRequestProcessed += (sender, args) => { TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_eventChannel); }; // When IMessagingInvitation invitation = await m_communication.StartMessagingAsync("Test message", "sip:[email protected]", "https://example.com/callback").ConfigureAwait(false); // Then Assert.IsNotNull(invitation); Assert.IsNotNull(invitation.RelatedConversation); Assert.IsTrue(m_restfulClient.RequestsProcessed("POST " + DataUrls.MessagingInvitations)); }
public async void TestSetup() { m_loggingContext = new LoggingContext(Guid.NewGuid()); var data = TestHelper.CreateApplicationEndpoint(); m_mockEventChannel = data.EventChannel; m_restfulClient = data.RestfulClient; ApplicationEndpoint applicationEndpoint = data.ApplicationEndpoint; await applicationEndpoint.InitializeAsync(m_loggingContext).ConfigureAwait(false); await applicationEndpoint.InitializeApplicationAsync(m_loggingContext).ConfigureAwait(false); ICommunication communication = applicationEndpoint.Application.Communication; m_restfulClient.HandleRequestProcessed += (sender, args) => { TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.MessagingInvitations, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_mockEventChannel); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.EstablishMessagingCall, HttpMethod.Post, "Event_MessagingInvitationStarted.json", m_mockEventChannel); // Message completed event has to be delivered after the response, so start a new thread to wait some time before delivering the event if (m_deliverMessageCompletedEvent) { Task.Run(async() => { await Task.Delay(TimeSpan.FromMilliseconds(10)).ConfigureAwait(false); TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.SendMessage, HttpMethod.Post, "Event_MessageCompleted.json", m_mockEventChannel); }); } }; // Establish a messaging call IMessagingInvitation invitation = await communication.StartMessagingWithIdentityAsync( "Test subject", "sip:[email protected]", "https://example.com/callback", "Local user", "sip:[email protected]", m_loggingContext).ConfigureAwait(false); TestHelper.RaiseEventsFromFile(m_mockEventChannel, "Event_ConversationConnected.json"); // It has link to the messaging call TestHelper.RaiseEventsFromFile(m_mockEventChannel, "Event_ParticipantAdded.json"); TestHelper.RaiseEventsFromFile(m_mockEventChannel, "Event_MessagingConnected.json"); // It has the messaging call m_messagingCall = invitation.RelatedConversation.MessagingCall; }
public async Task StartAdhocMeetingShouldNotPassCallbackContextInTheHttpRequest() { // Given var callbackContextNotPassed = false; m_messagingInvitation = await StartIncomingMessagingInvitationAsync("Event_IncomingIMCall.json").ConfigureAwait(false); m_restfulClient.HandleRequestProcessed += (sender, args) => { var operationId = TestHelper.RaiseEventsOnHttpRequest(args, DataUrls.StartAdhocMeeting, HttpMethod.Post, "Event_OnlineMeetingInvitationStarted.json", m_mockEventChannel); if (operationId != null) { var input = args.Input as StartAdhocMeetingInput; callbackContextNotPassed = input.CallbackContext == null; } }; // When await m_messagingInvitation.StartAdhocMeetingAsync("Test subject", "https://example.com/callback", m_loggingContext).ConfigureAwait(false); // Then Assert.IsTrue(callbackContextNotPassed); }
public Task <IOnlineMeetingInvitation> StartAdhocMeetingAsync(IMessagingInvitation invitation, string subject, string callbackContext, LoggingContext loggingContext = null) { return((invitation as MessagingInvitation).StartAdhocMeetingAsync(subject, callbackContext, null, loggingContext)); }
private async Task StartInstantMessagingBridgeFlowAsync(IncomingInviteEventArgs <IMessagingInvitation> e) { Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] StartInstantMessagingBridgeFlow: LoggingContext: {0}", LoggingContext)); CallbackContext callbackcontext = new CallbackContext { InstanceId = this.InstanceId, JobId = this.JobId }; string callbackContextJsonString = JsonConvert.SerializeObject(callbackcontext); string CallbackUrl = string.Format(CultureInfo.InvariantCulture, AzureApplication.CallbackUriFormat, HttpUtility.UrlEncode(callbackContextJsonString)); string meetingUrl = string.Empty; //There will be two conversation legs for the saas app m_p2pConversation = null; m_confConversation = null; #region Step 1 Start adhoc meeting //Step1: Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] Step 1: Start adhoc meeting: LoggingContext: {0}", LoggingContext)); IOnlineMeetingInvitation onlineMeetingInvite = await e.NewInvite.StartAdhocMeetingAsync(m_handleIncomingMessageInput.Subject, CallbackUrl, LoggingContext).ConfigureAwait(false); if (string.IsNullOrEmpty(onlineMeetingInvite.MeetingUrl)) { throw new PlatformserviceApplicationException("Do not get valid MeetingUrl on onlineMeetingInvitation resource after startAdhocMeeting!"); } meetingUrl = onlineMeetingInvite.MeetingUrl; Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] Get meeting uri: {0} LoggingContext: {1}", onlineMeetingInvite.MeetingUrl, LoggingContext)); //wait on embedded onlinemeetingInvitation to complete, so that we can have valid related conversation await onlineMeetingInvite.WaitForInviteCompleteAsync().ConfigureAwait(false); //this is conference conversation leg m_confConversation = onlineMeetingInvite.RelatedConversation; if (m_confConversation == null) { throw new PlatformserviceApplicationException("onlineMeetingInvite.RelatedConversation is null? this is propably app code bug!"); } #endregion #region Step 2 add Messaging modality on conference conversation //Step2: Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] Step2: add Messaging modality on conference conversation: LoggingContext: {0}", LoggingContext)); IMessagingCall confMessaging = m_confConversation.MessagingCall; if (confMessaging == null) { throw new PlatformserviceApplicationException("[InstantMessagingBridgeFlow] No valid Messaging resource on conference conversation"); } //Hook up the event handler on "MessagingModality" of the conference leg and make sure what ever message anon user , or agent input , the app can all know and note down confMessaging.IncomingMessageReceived += OnIncomingMessageReceived; m_confConversation.HandleParticipantChange += this.OnParticipantChange; IMessagingInvitation messageInvitation = await confMessaging.EstablishAsync(LoggingContext).ConfigureAwait(false); await messageInvitation.WaitForInviteCompleteAsync().ConfigureAwait(false);//messageInvitation cannot be null here #endregion #region Step 3 Start AcceptAndBridge //Step3: Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] Step3: Start AcceptAndBridge: LoggingContext: {0}", LoggingContext)); await e.NewInvite.AcceptAndBridgeAsync(LoggingContext, meetingUrl, m_handleIncomingMessageInput.Subject).ConfigureAwait(false); await e.NewInvite.WaitForInviteCompleteAsync().ConfigureAwait(false); m_p2pConversation = e.NewInvite.RelatedConversation; //This is to clean the conf conversation leg when the p2p conversation is removed m_p2pConversation.HandleResourceRemoved += (o, args) => { m_p2pConversation.HandleResourceRemoved = null; this.OnClientChatDisconnected(); }; IMessagingCall p2pMessaging = m_p2pConversation.MessagingCall; if (p2pMessaging == null || p2pMessaging.State != Rtc.Internal.Platform.ResourceContract.CallState.Connected) { Logger.Instance.Error(string.Format("[InstantMessagingBridgeFlow] p2pMessaging is null or not in connected state: LoggingContext: {0}", LoggingContext)); throw new PlatformserviceApplicationException("[InstantMessagingBridgeFlow] p2pMessaging is null or not in connected state"); } #endregion #region Step 4 Send welcome message //Step4: Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] Step4: Send welcome message: LoggingContext: {0}", LoggingContext)); await p2pMessaging.SendMessageAsync(m_handleIncomingMessageInput.WelcomeMessage, LoggingContext).ConfigureAwait(false); #endregion #region Step 5 Add bridged participant to enable agent send message to client chat //Step5: Logger.Instance.Information(string.Format("[InstantMessagingBridgeFlow] Step5: Add bridged participant to enable agent send message to client chat. LoggingContext: {0}", LoggingContext)); IConversationBridge conversationBridge = m_p2pConversation.ConversationBridge; if (conversationBridge == null) { Logger.Instance.Error(string.Format("[InstantMessagingBridgeFlow] conversationBridge == null after accept and bridge. LoggingContext: {0}", LoggingContext)); throw new PlatformserviceApplicationException("[InstantMessagingBridgeFlow] conversationBridge == null after accept and bridge"); } await conversationBridge.AddBridgedParticipantAsync(LoggingContext, m_handleIncomingMessageInput.InvitedTargetDisplayName, m_handleIncomingMessageInput.InviteTargetUri, false).ConfigureAwait(false); #endregion #region Step 6 Start addParticipant to conference //Step 6: Logger.Instance.Information(string.Format("[HandleIncomingMessageJob] Step5: Start addParticipant to conference: LoggingContext: {0}", LoggingContext)); IParticipantInvitation participantInvitation = await m_confConversation.AddParticipantAsync(m_handleIncomingMessageInput.InviteTargetUri, LoggingContext).ConfigureAwait(false); await participantInvitation.WaitForInviteCompleteAsync().ConfigureAwait(false); #endregion }
/// <summary> /// Implement the interface ExecuteCoreAsync /// </summary> /// <returns></returns> public override async Task ExecuteCoreAsync() { ICommunication communication = AzureApplication.ApplicationEndpoint.Application.Communication; //Construct callbackUrl with callbackContext for callback message routing CallbackContext callbackcontext = new CallbackContext { InstanceId = this.InstanceId, JobId = this.JobId }; string callbackContextJsonString = JsonConvert.SerializeObject(callbackcontext); string CallbackUrl = string.Format(CultureInfo.InvariantCulture, AzureApplication.CallbackUriFormat, HttpUtility.UrlEncode(callbackContextJsonString)); Logger.Instance.Information("[SimpleNotifyJob] start to send messaging invitation"); SimpleNotifyJobInput jobinput = this.JobInput as SimpleNotifyJobInput; if (jobinput == null) { throw new InvalidOperationException("Failed to get SimpleNotifyJobInput instance"); } IMessagingInvitation invite = null; try { //Invite resource will be there when this taskc completes invite = await communication.StartMessagingAsync("Notification", jobinput.TargetUri, CallbackUrl, LoggingContext).ConfigureAwait(false); //Waiting for invite complete await invite.WaitForInviteCompleteAsync().ConfigureAwait(false); IMessagingCall messagingCall = invite.RelatedConversation.MessagingCall; messagingCall.IncomingMessageReceived += OnIncomingMessageReceived; Logger.Instance.Information("[SimpleNotifyJob] sending notification message"); await messagingCall.SendMessageAsync(jobinput.NotificationMessage, LoggingContext).ConfigureAwait(false); Task reseponseReceived = m_responseMessageNotified.Task; try { await reseponseReceived.TimeoutAfterAsync(TimeSpan.FromSeconds(30)).ConfigureAwait(false); } catch (TimeoutException) { Logger.Instance.Warning("[SimpleNotifyJob] Do not get a response with in 30 seconds"); } if (reseponseReceived.IsCompleted) { Logger.Instance.Information("[SimpleNotifyJob] sending thank you message"); await messagingCall.SendMessageAsync("Thank you!", LoggingContext).ConfigureAwait(false); } } catch(CapabilityNotAvailableException ex) { Logger.Instance.Error("[SimpleNotifyJob] Failed!", ex); } catch(RemotePlatformServiceException ex) { Logger.Instance.Error("[SimpleNotifyJob] Failed!", ex); } finally { if (invite?.RelatedConversation != null) { await invite.RelatedConversation.DeleteAsync(LoggingContext).ConfigureAwait(false); } } }