How can I retrieve the call forwarding rules (routing) of a Lync client in a Managed SIP Application (serverside technologies like MSPL or UCMA)? The only thing I found is an Article on how you can do it clientside with the Lync SDK.
Also this Answer and this MSDN Article and this Question seem to indicate that it does work but I need this setting at a specific moment (if the User is online or not) and not as soon as he logs into his Lync account and publishes his presence info, as seen in link #1. Also it is necessary to get this for any client without creating an UserEndpoint first. So it would be best if this is possible with an ApplicationEndpoint (or another method).
As far as I found out, it should be possible to retrieve the forwarding settings from the presence metadata, but I do not get this information.
var categories = new string[] {
"state",
//"routing" // ?
};
var asyncresult = presenceSvc.BeginPresenceQuery(sips, categories, null, null, null);
var result = presenceSvc.EndPresenceQuery(asyncresult).ToList();
You cannot do it with an ApplicationEndpoint. You must have an UserEndpoint.
However, you can create a UserEndpoint who just need the CollaborationPlateform and the SipUser and not any passwords.
For my application, I decompiled SEFAUtil.exe via ILSpy to understand how they did in their programs. I advise you to take a look at it.
This is my technique to make it works:
1/ Creation of the UserEndPoint
When creating the user endpoint you have to subscribe for this presence to get the information even if is not connected
userEndpoint.LocalOwnerPresence.BeginSubscribe(null, null);
2/ Subscribe to PresenceNotificationReceived Event
userEndpoint.LocalOwnerPresence.PresenceNotificationReceived += OnCategoryNotificationReceived;
private static void OnCategoryNotificationReceived(object sender, LocalPresentityNotificationEventArgs e)
{
// Here you get the PresenceCategory and all the data of the user
foreach (PresenceCategoryWithMetaData current in e.AllCategories)
{
if (current.Name == "routing" && current.ContainerId == 0 && current.InstanceId == 0L)
// Creation of your Routing, I stock it in a Property
_routingCategory = new Routing(current);
}
// I set my event to continue my main thread
_routingCategoryUpdated.Set();
}
3/ Display the information you want
// Wait until you get the information of the user
if (!_routingCategoryUpdated.WaitOne(10000))
{
Console.WriteLine("TimeOut Getting Informations");
return;
}
// Just display all the data you can need
else
{
Console.WriteLine($"User Aor: {userEndPointTarget.OwnerUri}");
Console.WriteLine($"Display Name: {userEndPointTarget.OwnerDisplayName}");
Console.WriteLine($"UM Enabled: {userEndPointTarget.UmEnabled}");
Console.WriteLine($"Simulring enabled: {_routingCategory.SimultaneousRingEnabled}");
if (_routingCategory.SimultaneousRingEnabled && _routingCategory.SimultaneousRing != null)
{
foreach (string time in _routingCategory.SimultaneousRing)
{
Console.WriteLine($"Simul_Ringing to: {time}");
}
}
if (_routingCategory.DelegateRingEnabled)
{
if (_routingCategory.SkipPrimaryEnabled)
{
Console.Out.Write("Forwarding calls to Delegates: ");
}
else if (_routingCategory.UserWaitTimebeforeTeamOrDelegates.TotalSeconds > 0.0)
{
Console.Out.Write($"Delay Ringing Delegates (delay:{ _routingCategory.UserWaitTimebeforeTeamOrDelegates.TotalSeconds} seconds): ");
}
else
{
Console.Out.Write("Simultaneously Ringing Delegates: ");
}
foreach (string delegateCurrent in _routingCategory.Delegates)
{
Console.Out.Write($"{delegateCurrent} ");
}
Console.Out.WriteLine();
}
else if (_routingCategory.TeamRingEnabled)
{
if (_routingCategory.UserWaitTimebeforeTeamOrDelegates.TotalSeconds > 0.0)
{
Console.Out.Write($"Delay Ringing Team (delay:{_routingCategory.UserWaitTimebeforeTeamOrDelegates.TotalSeconds} seconds). Team: ");
}
else
{
Console.Out.Write("Team ringing enabled. Team: ");
}
foreach (string currentTeam in _routingCategory.Team)
{
Console.Out.Write($"{currentTeam} ");
}
Console.Out.WriteLine();
}
else if (_routingCategory.CallForwardToTargetsEnabled)
{
if (_routingCategory.CallForwardingEnabled)
{
Console.Out.WriteLine($"Forward immediate to: {_routingCategory.CallForwardTo}");
}
else
{
Console.Out.WriteLine($"User Ring time: {_routingCategory.UserOnlyWaitTime}");
Console.Out.WriteLine($"Call Forward No Answer to: {_routingCategory.CallForwardTo[0]}");
}
}
else if (userEndPointTarget.UmEnabled)
{
Console.Out.WriteLine($"User Ring time: {_routingCategory.UserOnlyWaitTime}");
Console.Out.WriteLine("Call Forward No Answer to: voicemail");
}
else
{
Console.Out.WriteLine("CallForwarding Enabled: false");
}