UCMA 3.0を使用して、サービスとして実行され、インスタントメッセージ呼び出しの形式で定期的に「ブロードキャスト」を送信するアプリケーションを開発しています。私は「MicrosoftLyncServer2010を使用したプロフェッショナルユニファイドコミュニケーション開発」という本を使用しており、すべてが正常にプロビジョニングされており、アプリケーションエンドポイントを確立できます。
しかし、私は2つの側面に固執しています。
1) Lyncのすべてのユーザーのリストを取得するにはどうすればよいですか?UCMAが実行できることはすべて、1人のユーザーに集中しています。たとえば、特定のユーザーの「連絡先リスト」に存在するすべての連絡先/グループを取得できますが、それらの連絡先リストの1つに追加できる利用可能な連絡先のリストを照会する手段はありません。MSDNフォーラムでこの投稿を見つけたので、ADに直接問い合わせることが最善の策だと思いました。
2)実際にブロードキャストスタイルのIMを送信するための最良の方法は何ですか?私の作業の前提は、このコード例で見つけたようなもの(具体的にはpublic void SendIM()
メソッド)を試すことです。
したがって、ADから受信者のリストを取得し(それぞれをループして現在のプレゼンスを確認しますか?)、自動化を使用してコレクション内の各受信者に対してIM呼び出しを行います。
それは理にかなっていますか?受信者のプレゼンスを確認する必要がありますか、それとも現在のプレゼンスステータスに関係なく、楽観的にIM呼び出しを行うだけですか?IMブロードキャストの送信を示す実用的なコードを誰かに教えてもらえますか?これはおそらく最も一般的なユースケースの1つであると思われるかもしれませんが、SDKサンプルではカバーされていません。前もって感謝します。
更新: リスターが言うように、「ブロードキャスト」メソッドはありません。受信者をループして、各受信者に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);
}
}