0

so when someone is calling me I want to get his phonenumber.

Contact inviter = conversation.Properties[ConversationProperty.Inviter] as Contact; // The person that is calling
ContactEndpoint inviterContactEndpoint = inviter.Settings[ContactSetting.DefaultContactEndpoint] as ContactEndpoint;

How do I get it?

Using this

string phoneNumber = inviterContactEndpoint.Uri;

returns me from Skype to Skype

enter image description here

and from phone to Skype

enter image description here

I also tried using

inviter.GetContactInformation(ContactInformationType);

but ContactInformationType has no phone number property.

1 Answers1

0

You use GetContactInformation method to get a list of ContactEndpoint objects. Now you can go through the list and find the phone number type that you want.

e.g.

var contactEndpoints = (Contact.GetContactInformation(ContactInformationType.ContactEndpoints) as List<object> ?? new List<object>()).Select(_ => _ as ContactEndpoint).Where(_ => _ != null);
foreach (var contactEndpoint in contactEndpoints)
{
    switch (contactEndpoint.Type)
    {
        case ContactEndpointType.WorkPhone:
            break;
        case ContactEndpointType.MobilePhone:
            break;
        case ContactEndpointType.HomePhone:
            break;
        case ContactEndpointType.OtherPhone:
            break;
        case ContactEndpointType.Lync:
            break;
        case ContactEndpointType.VoiceMail:
            break;
        case ContactEndpointType.Invalid:
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

Now the problem you will have is that for non-cached contact's ContactInformationType.ContactEndpoints will return null (or a empty list, I forget which).

So you need to understand to get this information will not happen synchronously. If you really want this information you need to request it and it will come in a event update for the contact object. To do this you need to create a contact subscription for the details that you want and then subscribe specific contacts to the subscriptions.

Setup a subscription using the client ContactManager on app startup:

_contactSubscription = _client.ContactManager.CreateSubscription();
_contactSubscription.Subscribe(ContactSubscriptionRefreshRate.High,
    new[]
        {
            ContactInformationType.ContactEndpoints
        });
            }
            catch (Exception e)
            {
                Log.WriteLine(e);
                _mediator.ClientComConnectionDead();
            }
    }

Setup the contact and subscribe to contact changes:

contact.ContactInformationChanged += ContactOnContactInformationChanged;
_contactSubscription.AddContact(contact);

Handle the updated contact information:

private void ContactOnContactInformationChanged(object sender, ContactInformationChangedEventArgs e)
{
    if (e.ChangedContactInformation.Any(_ => _ == ContactInformationType.ContactEndpoints))
    {
        var contactEndpoints = (Contact.GetContactInformation(ContactInformationType.ContactEndpoints) as List<object> ?? new List<object>()).Select(_ => _ as ContactEndpoint).Where(_ => _ != null);
        foreach (var contactEndpoint in contactEndpoints)
        {
            switch (contactEndpoint.Type)
            {
                case ContactEndpointType.WorkPhone:
                    break;
                case ContactEndpointType.MobilePhone:
                    break;
                case ContactEndpointType.HomePhone:
                    break;
                case ContactEndpointType.OtherPhone:
                    break;
                case ContactEndpointType.Lync:
                    break;
                case ContactEndpointType.VoiceMail:
                    break;
                case ContactEndpointType.Invalid:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }
}

When you are finished with the contact you need to unhook and cleanup:

contact.ContactInformationChanged -= ContactOnContactInformationChanged;
_contactSubscription.RemoveContact(contact);

When you are finished with the subscription you need to unsubscribe at the application cleanup:

_contactSubscription.Unsubscribe();

The contact updates can come in at any time and also at multiple times or may not be updated at all if there is no contact endpoints. The backend for this is the AD contact information, so if the AD contact updates then you will be sent a update to the information that you have subscribed to.

This interface is not really for asking for contact information and getting a answer back, it's more for hooking up to userinterface elements so that they can be updated in realtime while they are currently being displayed.

Shane Powell
  • 13,698
  • 2
  • 49
  • 61
  • thanks, but `ContactInformationType.ucPresenceContactEndpoints` does not exist, I think I have to take `ContactInformationType.ContactEndpoints`. Within the switch statement how can I get the phone number from the contactEndpoint? And how do I get the number from `ContactEndpointType.Lync` ? –  Aug 24 '18 at 07:45
  • I just tested the code, when someone is calling or sending a message to me, the event does not trigger. I tried to recreate yor suggestions and created a small example with a callstack from top to bottom https://hastebin.com/mufesotawu.cs maybe I am missing something but I think this is your suggested code –  Aug 24 '18 at 09:48
  • sorry `contactEndpoint` will represent the phone number. But still the event does not trigger. –  Aug 24 '18 at 10:38
  • Sorry, ContactInformationType.ContactEndpoints is the correct value like you say, I've edited the code. This was a copy paste error. – Shane Powell Aug 24 '18 at 20:53
  • The number is in Uri property of the ContactEndpoint in the form of a SIP uri, so a telephone number will be in E164 format e.g. tel:+6491234567 - https://learn.microsoft.com/en-us/dotnet/api/microsoft.lync.model.contactendpoint.uri?view=lync-client#Microsoft_Lync_Model_ContactEndpoint_Uri – Shane Powell Aug 24 '18 at 20:56
  • I know the code works as I have lots of code that requires it to work. Your link to your code doesn't work (shows no code). In my code I lookup the contact via the contact manager (based on searching). That may be different from the a contact from a conversation. Did you ask for the contactendpoints before hooking up the subscription? Maybe subscribe to more data types? My list is very large, I pretty much subscribe to all contact data types. https://learn.microsoft.com/en-us/dotnet/api/microsoft.lync.model.contactinformationtype?view=lync-client – Shane Powell Aug 24 '18 at 21:18
  • I will provide two snippets here (I hope one of them works now) https://hastebin.com/usenuvetec.cs and https://pastebin.com/pvQBeHF6 and please have a look at the comment `// THIS IS ALWAYS FALSE`. You can read the code from top to bottom it's the call order –  Aug 27 '18 at 09:54
  • When someone calls or sends a direct message this if statement will always return false / the breakpoint returns me false –  Aug 27 '18 at 09:54
  • The second link works for me, the first gives me a blank page. Your problem is that ContactSubscription only lasts for the length of the CreateContactEndpointSubscription. If you look at me answer I say: "Setup a subscription using the client ContactManager on app startup". So your ContactSubscription has to last for the length of the time that you need to be want updates. So if you make it the length of your detected LyncClient logged in state then you should be fine. – Shane Powell Aug 27 '18 at 18:09
  • Also you should also try to get the ContactEndpoints after you directly get the Contact object as they may be cached (all your "favourite" contacts are cached) so it *may* work. – Shane Powell Aug 27 '18 at 18:13
  • I updated my code as you suggested https://pastebin.com/ENbgTvtC ( https://hastebin.com/akubecikaf.cs ) but the code still fails at `ContactInformationChanged` meaning the first if returns false –  Aug 28 '18 at 09:10
  • the short term is: I created `SetContactSubscription()` and call it after setting up the LyncClient –  Aug 28 '18 at 09:19
  • I think you should remove the "contactSubscription.RemoveContact(contact);" as you may miss the update for the ContactEndpoints. I would only do the remove contact once you have got the data that you wanted... There is no guarantee that the callback is just for the data that you asked for. The Lync client may do it's own thing as well. – Shane Powell Aug 28 '18 at 21:43
  • There is also NO guarantee that the Contact that you have has any ContactEndpoints at all... You can "manually" test this in the Lync interface, by doing a search for the contact and looking in the contact card for the information... This will roughly tell you what you should see from using the API. – Shane Powell Aug 28 '18 at 21:46