1

I have an application that uses Lync SDK 2013.

My application is linked with my phone, and when i receive a call my precence Lync become Busy (ContactAvilability.Busy) and when i terminate the call, i want to return my presence to its original state (Available or Do Not Disturb ....).

My question is how can i save my actual state, and return to it when i finish the call ??

public static void notify(Call call)
        {
            // How to save my current state
            if (call.state == Answer)
            {
                client.Self.BeginPublishContactInformation(
                new Dictionary<PublishableContactInformationType, object>() {
                {    PublishableContactInformationType.Availability, ContactAvailability.Busy }
                }, null, null);
            }
            else 
            {
                // where i want to return to my original state 
            }
        }

Thanks

J-Go
  • 115
  • 1
  • 1
  • 8

1 Answers1

0

To save the previous presence:

_previousPresence = client.Self.Contact.GetContactInformation(new[]
{
    ContactInformationType.Availability,
    ContactInformationType.ActivityId,
    ContactInformationType.CustomActivity
});

To restore is a little difficult because of the "Custom" activity which we get only the custom activity localized string but not the custom activity id. Also there is no way to restore a "unknown" custom activity (i.e. a custom activity presence that is not defined in the custom activities xml file for the client, this can happen where a UCMA endpoint or another client endpoint has custom activities setup not defined on this client). The only way to save and restore the presence exactly in all cases is to use a UCMA application (server or client) which gives you more control over what/how the presence is set i.e. fine grained control over custom activity presence types.

Example of restoring the presence from the Lync Client:

var publishData = new Dictionary<PublishableContactInformationType, object>
{
    {PublishableContactInformationType.Availability, _previousPresence[ContactInformationType.Availability]},
    {PublishableContactInformationType.ActivityId, _previousPresence[ContactInformationType.ActivityId]}
};

var customId = FindCustomActivityId(client,
    (ContactAvailability)_previousPresence[ContactInformationType.Availability],
    ((List<object>)_previousPresence[ContactInformationType.CustomActivity]).Cast<LocaleString>().ToList());
if (customId != null)
{
    publishData.Add(PublishableContactInformationType.CustomActivityId, customId);
}

await Task.Factory.FromAsync(client.Self.BeginPublishContactInformation(publishData, null, null), client.Self.EndPublishContactInformation);

The FindCustomActiviyId is a bit of a "hack" in that it doing a string compare search from the presvious presence information does not give back the custom activity id but only the localized string from the custom activity.

private static object FindCustomActivityId(Client client, ContactAvailability availability, IReadOnlyCollection<LocaleString> customActivities)
{
    var currentLcid = System.Globalization.CultureInfo.CurrentUICulture.LCID;
    var customStates = client.Self.GetPublishableCustomAvailabilityStates(currentLcid);

    if (customStates == null || !customStates.Any())
    {
        return null;
    }

    var state = customStates.FirstOrDefault(cs => customActivities.Any(ca => cs.Availability == availability && string.Equals(ca.Value, cs.Activity)));

    return state?.Id;
}

You may like to also take into account overlapping calls. i.e. your phone call and a Lync call overlapping. In these cases the Lync Client presence may already be on the "OnThePhone" busy state. Or if the presence changes to "OnThePhone" while after you answer your other phone system call.

Also you may like to set the busy sub-state to OnThePhone as well so that other Lync Users know you are on a call. This is what the Lync client is doing for you automatically when you answer a Lync Client call.

// publish on-the-phone presence
var publishData = new Dictionary<PublishableContactInformationType, object>
{
    {PublishableContactInformationType.Availability, ContactAvailability.Busy},
    {PublishableContactInformationType.ActivityId, "on-the-phone"}
};
await Task.Factory.FromAsync(client.Self.BeginPublishContactInformation(publishData, null, null), client.Self.EndPublishContactInformation);
Shane Powell
  • 13,698
  • 2
  • 49
  • 61
  • My notify(Call) goes through several states before being finished. Ringing => Answer => Terminate , So at furst time when 'Ringing' it saves the _previousPresence and in the else (call.state != Answer) return this _previousPresence, Ok. But when i answer, it saves before _previousPresence and then change the state to Busy (because the if(call.state == answer) is true), and when i terminate the call, before it saves _previousPresence (in this case :_previousPresence = busy)then goes through the else, and restore the _previousPresence = Busy. So in the end of my Call the presence is always Busy. – J-Go Nov 16 '17 at 12:33
  • I'm not sure I follow your logic. I would save the presence just before changing the presence not sometime before. The ringing state can take awhile where your local lync presence can change in the meantime. Your phone system most likely goes through many states, so don't forget the on-hold / resume states. The resume states can show up as "answered" again in some systems. – Shane Powell Nov 17 '17 at 01:57
  • Thanks a lot for your answer and explanation. – J-Go Nov 17 '17 at 08:25
  • It works very well. Thanks again. I just checked to save the _previousPrecence in the case : Ringings. – J-Go Nov 17 '17 at 11:06