Bridge Communications

Saturday, June 18, 2016

Skype for Business Response Group Add-on - Part III

This week we continue our series on the Response Group Add-in before we release it to the world next week.  Let's focus today on the logic involved to make the changes to the local Skype for Business client around the business logic of our agent.  We have a timer that is running in the background, to help is with this, and there are several things it is going to monitor and react to.

1.  On a call - When we are on a call we want to do nothing, we leave the existing "In a call" status as is.

2.  Conversation Removed - If a conversation is removed we want to check to see if there are any other audio calls remaining, and if not, we are going to busy out for our settings defined wrap up time.


private void ConversationManager_ConversationRemoved(object sender, Microsoft.Lync.Model.Conversation.ConversationManagerEventArgs e)
        {
            try
            {
                if (!Globals.HasAudioCall())
                {
                    Task.Factory.StartNew(() => 
                    {
                        Globals.isWrapUp = true;
                        System.Threading.Thread.Sleep(1000);
                        Globals.setLyncStatus(ContactAvailability.Busy, "Wrapping Up", "Wrapping Up");
                        System.Threading.Thread.Sleep(Convert.ToInt32(Globals.GetKey("WrapTime")) * 1000);
                        Globals.isWrapUp = false;
                    });
                }
            }
            catch { }
        }

3.  The Main Timer - The rest of the logic is handled by our main timer event.

 private void MainT_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                if (!Globals.isWrapUp)
                {
                    if (!Globals.HasAudioCall())
                    {
                        Globals.setLyncStatus(ContactAvailability.Free, "Ready for Call", "Available");

                        try
                        {
                            if (!string.IsNullOrEmpty(yourloc))
                            {
                                if (Globals.GetKey("PublishLocation") == "1")
                                {
                                    Globals.setLyncLocation(yourloc);
                                }
                            }
                        }
                        catch { }
                    }
                    else
                    {
                        Globals.myStatus = "In a Call";
                    }
                }
            }
            catch { }

            try
            {
                Task.Factory.StartNew(() => 
                {
                    this.Dispatcher.BeginInvoke((Action)(() =>
                    {
                        sbStatus.Text = Globals.myStatus;
                    }));
                });
            }
            catch { }
        }

You can see if we are in wrap up mode we won't set the user to available, and if the user is in an audio call we won't either.  Every other time this runs it will make sure the user is online and ready to take the next call, with one big exception.  If the client becomes idle away, ie Lync/S4B detects the user has wandered off it sets the status to Away.  This cannot be undone programatically, and should be noted before using this or any other similar program.

Here is the code that actually does the publishing of the presence in our Globals class.

 public static void setLyncStatus(ContactAvailability newState, string activityId, string newstatustext)
        {
            myStatus = newstatustext;

            try
            {
                Dictionary<PublishableContactInformationType, object> publishData = new Dictionary<PublishableContactInformationType, object>();

                if ((ContactAvailability)lc.Self.Contact.GetContactInformation(ContactInformationType.Availability) != newState)
                {
                    publishData.Add(PublishableContactInformationType.Availability, newState);
                }

                if (!string.IsNullOrEmpty(activityId))
                {
                    publishData.Add(PublishableContactInformationType.PersonalNote, activityId);
                }

                if (!string.IsNullOrEmpty(newstatustext))
                {
                    publishData.Add(PublishableContactInformationType.ActivityId, newstatustext);
                }

                object[] asyncState = { lc.Self };

                lc.Self.BeginPublishContactInformation(publishData, null, asyncState);
              
            }
            catch
            { }
        }

Next week we will wrap up this series and post the install on technet for everyone to play with.


Doug Routledge, C# Lync, Skype for Business, SQL, Exchange, UC Developer  BridgeOC
Twitter - @droutledge @ndbridge





No comments:

Post a Comment