After (with a small detour to makeMeAvailable) UCWA is ready for an important task, Communication and more specifically Conversation and Conferencing. I felt the need to combine discussion on the two topics as it allows me to cover some of the differences that will need to be handled depending on how the UCWA user participates in communication. Many of these traces were created with the UCWA helper libraries (specifically the Instant Messaging task).
Some base documentation on how to send an outgoing IM can be found at: KeyTasks-Communication-OutgoingIMCall
Two Routes, well really four paths...
Using the umbrella, Communication, to describe Conversation and Conferencing, it is possible to identify the two routes as either incoming or outgoing.
This gives the following as a map of communications:
- messagingInvitation - Conversation
- onlineMeetingInvitation - Conference
- startMessaging - Conversation
- startOnlineMeeting - Conference
The messagingInvitation as seen above contains basic information about who invited (messagingInvitation._embedded.from) and a series of links to accept, decline, and view the invite message. Following the accept href will join the user into the Conversation and cause the event channel to propagate more conversation and messaging events.
Similar to a messagingInvitation, an onlineMeetingInvitation contains information about invited, but since it is a conference it also contains conference information (onlineMeetingUri and supported modalities). To join the Conference just follow the accept href, but be warned that unlike a Conversation it will not have messaging as a default modality. Instead the event channel will indicate that messaging is in a Disconnected state:
A POST request on the addMessaging href will add the UCWA user to the messaging modality of the Conference and the event channel will propagate a messaging event with a Connected state. How retrieve these links in the event this information was missed will be described in the following sections.
This is how a UCWA user initiates a messaging Conversation as seen in KeyTasks-Communication-OutgoingIMCall. Starting this process will create a messagingInvitation for the other user (could be UCWA, Lync, etc).
This is how a UCWA user initiates a Conference and will have to wait until a later time to discuss it further (sadly).
So I've joined a Conversation/Conference... now what?
Joining either a Conversation or Conference the event channel with propagate many conversation-related events. The most important (for me at least) is what I tend to call the messaging links which is an event containing sendMessage, setIsTyping, and stopMessaging among others. It should be noted that you will want to see the event containing this data has a state of Connected:
If somehow this information does not show up in the event channel it is possible to start at applications and get to the links as follows:
- GET request on the root applications href
- GET request on _embedded.communication._links.conversations.href to get the active conversations
- GET request on the correct conversation under ._links.conversation
- GET request on _links.messaging.href
- Cache the important links in the response
Another important link to cache is addParticipant and can be found in event channel data for the conversation or in the above description in step 3 response data. With the set of links it is possible send messages, indicate UCWA user is typing, end the conversation, and add more participants (which may escalate the Conversation to a Conference!).
Sending and Receiving Messages
On the flip side of things, a message event in the event channel may contain a plainMessage encoded as data Url (The "data" URL scheme) which means decoding in some form to turn "href=data:text/plain;charset=utf-8,words+with+spaces" into "words with spaces":
Are you typing or not?
Using the setIsTyping href it indicates to the conversation/conference that the user is currently typing a message. Some rudimentary testing seems to lean toward the indication being active for about 10-15 seconds before it is no longer displayed. To continuously indicate a user is typing it should make subsequent posts when nearing the 15 second mark. An interesting side is that user typing will not pass through the event channel as a result of making the request on setIsTyping.
Is it over yet?
It is possible to end communication by making a POST request on stopMessaging which will trigger event channel data to notify that the user has disconnected any connected modalities (messaging, audio, etc) and deleted from participant/participantMessaging, conversation/conference, and related pieces:
The events seen above can help in understanding what happens when a conversation is terminated: messaging transitions to the disconnected state, localParticipant (Our user) deleted, participantMessaging (Our/other users) deleted and participant (other users) deleted. Tracking participant and participantMessaging for added/deleted can indicate when users are entering/leaving the conversation.
In the event that the conversation has not already been escalated to a Conference the state of the conversation will change to Conferencing and become Conferenced when the user accepts the invitation. As stated above in onlineMeetingInvitation, a UCWA user will see messaging in a Disconnected state and need to make a POST request on addMessaging to participate. In the cases where a Lync Client user is the third user added to the Conversation the preexisting UCWA users will still have valid messaging links.
Communication in UCWA covers a good portion of the interesting pieces of the API (Conversation and Conferencing) and is typically where event channel processing becomes important. Being able to send/receive messages, indicate typing, invite other users, and stop communication are the basics of chatting in Lync. With these basic it would be rather simple to work toward an anonymous chat client (using the anonymous meeting grant type) assuming access to a service providing meeting Uri(s).
I'll look at incorporating the information from this posting into an anonymous meeting join and visit a topic from Authentication I skipped, renewing OAuth tokens. I'll plan on providing a full trace and work from there as opposed to all the screenshots this run (mostly due to needing to look at both Conversation and Conference).