I have been a bit lax on finding aspects of UCWA that could use a bit of demystification, but it is not to say that there are not things I do not understand rather that I have not spent time thinking about some of the more unique scenarios. One of those scenarios is needing to re-join an in-progress conversation that the UCWA dropped out of. This can be achieved by utilizing the threadId parameter provided either when making the initial POST request to startMessaging or as part of event channel data included in messagingInvitation / conversation events. I'm re-purposing work done for UCWA by the numbers – #4 Anonymous Meeting Join and creating a sample that allows user sign-in (username and password) and starts a conversation with a specified user. Additional buttons will be present to leave and re-join the conversation. Refreshing the page will attempt to clean up the UCWA application similar to how anonymous meeting join cleaned up.
The sample I have in mind will make use of startMessaging providing operationId (required), to (required), threadId (optional). It is possible to not provide threadId and parse messagingInvitation or conversation event data to retrieve a generated threadId (as seen below).
Differences between Conversations and Meetings
One interesting situation I encountered when transitioning the code from meeting to conversation is how event data related to typingParticipants and message (other events exhibit this behavior, but are less important to this sample). Meeting events will contain a participant object that has a populated title property whereas conversation events do not. This immediately posed a problem due to the code structure of expecting to find this value to indicate who is typing or sent a message.
While this property value may not be available in certain circumstances it is possible to follow the participant href to get data stored in the meeting or conversation about the participant. This however had similar problems that a name property was not available to conversation, but by following the contact href it is possible to finally reach the name (or title).
I created an array of titles/names indexed by URI to track what users I had already executed the additional requests (as opposed to getting new contact information every new typingParticipants / message event). It was also important to track completed messagingInvitation and conversation events to determine if/when a remote participant declined the invitation or a failure occurred and when the conversation has ended.
Re-join a Conversation
After authenticating and starting a conversation with a remote participant it is possible to leave the conversation via Leave Conversation button. What I did notice is that after making the request to startMessaging with the original threadId is the UCWA joins a conversation while the remote user can take a short while before they re-join the conversation. I have actually seen two distinct behaviors surrounding this as follows:
- Lync Client is in background - Upon re-join request a popup message indicating that UCWA user is adding IM appears and both users appears in sample site under participants list
- Lync Client is in foreground - Upon re-join Lync conversation window blinks and only UCWA user appears in sample site under participants list
Eventually the remote participant appears in both situations, but it is a bit odd at first glance.
Traces and Code
Traces containing the differences between Meetings and Conversations are as follows:
- Conv (2 non-fed).saz - Conversation between 2 non-federated contacts
- Meeting (2 non-fed).saz - Meeting between 2 non-federated contacts
The code is structured as follows:
- Authentication.js - Version identical to AnonMeeting.7z
- AutoDiscovery.js - Version identical to AnonMeeting.7z
- Cache.js - Version identical to AnonMeeting.7z
- Events.js - Version identical to AnonMeeting.7z
- GeneralHelper.js - Version identical to AnonMeeting.7z
- index.html - Main site with modifications for Conversations
- RejoinConversation.js - Re-purposed logic from AnonMeeting.7z for handling buttons (start/leave/rejoin conversation, send message) and event handling
- Transport.js - Version identical to AnonMeeting.7z
- UcwaObject.js - Re-purposed logic from AnonMeeting.7z for handling AutoDiscovery, Authentication, and reportMyActivity
Sample code: RejoinConversation.7z
I am thinking about doing a short excerpt on how to parse HTTP links posted into a conversation from Lync/LWA as they can appear funky.