Search code examples
selflyncavailability

ContactAvailability Lync


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


Solution

  • 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);