我正在使用UCMA 3.0开发一个应用程序,该应用程序将作为服务运行,并以即时消息调用的形式发送定期“广播”。我一直在使用“Professional Unified Communications Development with Microsoft Lync Server 2010”这本书,并且配置完好,并且能够建立应用程序端点。
但我仍然坚持两个方面。
1)如何获取Lync的所有用户列表? UCMA所能做的一切都集中在一个用户身上。例如,它允许我检索给定用户的联系人列表上的所有联系人/组,但是没有提供任何方法来查询可以添加到其中一个联系人列表的可用联系人列表。在MSDN论坛上,我发现了这个post,这让我觉得我最好的选择就是直接查询AD。
2)实际发送广播风格IM的最佳方式是什么?我的工作前提是尝试类似我在code example(特别是public void SendIM()
方法)中找到的内容。
那么,从AD获取收件人列表,(在每个收件人上循环检查当前状态?),然后使用Automation为集合中的每个收件人进行IM调用。
这有意义吗?我是否需要检查收件人的存在?或者我是否只是乐观地进行IM调用而不管他们当前的状态?有人能指出一些演示发送IM广播的工作代码吗?您可能认为这可能是最常见的用例之一,但SDK示例并未涵盖它。提前谢谢。
更新 正如Lister所说,没有“广播”方法。我不得不循环接收者并拨打电话为每个收件人发送IM。我发现我还需要检查收件人状态,因为它会尝试将消息发送到离线,忙碌等用户,从而导致异常。最好只发送到某些在线状态。由于应用程序端点没有用户/组列表,您需要使用AD和目录服务确定收件人,或者只是维护自己的收件人列表。我最终编写了一个工作流程,用户可以将IM发送到自动机应用程序端点,以选择加入或选择退出警报广播。工作流维护一个简单的订户数据库表。
/// <summary>
/// Sending of the actual IM to broadcast subscribers. Here we check that the presence of the target recipient
/// is in fact suitable for us to barge in with an alert.
/// </summary>
private void sendIMBroadcast(string sipTarget, byte[] htmlBytes)
{
try {
_appEndpoint.PresenceServices.BeginPresenceQuery(
new List<string>() {sipTarget},
new string[] {"state"},
null,
result =>
{
try
{
// Retrieve the results of the query.
IEnumerable<RemotePresentityNotification> notifications = _appEndpoint.PresenceServices.EndPresenceQuery(result);
// Grab the first notification in the results.
RemotePresentityNotification notification = notifications.FirstOrDefault();
if (notification == null)
{
logger.Warn("Invalid recipient for P1 broadcast: {0}", sipTarget);
return;
}
//ensure presense is one we want to send alert to
//if (notification.AggregatedPresenceState.AvailabilityValue )
long v = notification.AggregatedPresenceState.AvailabilityValue;
bool skip = false;
if (v >= 3000 && v <= 4499)
{
//online
}
else if (v >= 4500 && v <= 5999)
{
//idle online
}
else if (v >= 6000 && v <= 7499)
{
//busy
skip = true;
}
else if (v >= 7500 && v <= 8999)
{
//idle busy
skip = true;
}
else if (v >= 9000 && v <= 11999)
{
//dnd
skip = true;
}
else if (v >= 12000 && v <= 14999)
{
//brb
skip = true;
}
else if (v >= 15000 && v <= 17999)
{
//away
skip = true;
}
else if (v >= 18000)
{
//offline
skip = true;
}
if (skip == true)
{
logger.Debug("Skipping broadcast for user '{0}' due to presense status {1}.", sipTarget, v.ToString());
return;
}
logger.Debug("Sending broadcast for user '{0}' with presense status {1}.", sipTarget, v.ToString());
// Send an IM, create a new Conversation and make call
Conversation conversation = new Conversation(_appEndpoint);
InstantMessagingCall _imCall = new InstantMessagingCall(conversation);
try
{
ToastMessage toast = new ToastMessage("Unassigned P1 Tickets!");
// Establish the IM call.
_imCall.BeginEstablish(sipTarget,
toast,
new CallEstablishOptions(),
result2 =>
{
try
{
// Finish the asynchronous operation.
_imCall.EndEstablish(result2);
_imCall.Flow.BeginSendInstantMessage(
new System.Net.Mime.ContentType("text/html"),
htmlBytes,
ar =>
{
try
{
_imCall.Flow.EndSendInstantMessage(ar);
}
catch (RealTimeException rtex)
{
logger.Error("Failed sending P1 Broadcast Instant Message call.", rtex);
}
},
null
);
}
catch (RealTimeException rtex)
{
// Catch and log exceptions.
logger.Error("Failed establishing IM call", rtex);
}
},
null
);
}
catch (InvalidOperationException ioex)
{
logger.Error("Failed establishing IM call", ioex);
}
}
catch (RealTimeException ex)
{
logger.Error("Presence query failed.", ex);
}
},
null);
}
catch (InvalidOperationException ex)
{
logger.Error("Failed accepting call and querying presence.", ex);
}
}
答案 0 :(得分:1)
实际上没有“广播IM”你可以迭代你从AD获得的sip地址列表并在每个SIP地址上执行BeginStartConversation