Skype for Business の機能をアプリに追加してみよう その 1

今回から数回で、C# を使った、開発中のアプリケーションに Skype for Business の機能を組み込む方法を紹介します。

Unified Communications Web API (UCWA)

UCWA は Skype for Business (オンライン/設置型ともに) の機能を、簡単気軽に REST で呼び出せる API です。概要や基本的な使い方については、以下のブログがわかりやすいので参考にしてみてください。

https://blogs.msdn.microsoft.com/tsmatsuz/2013/03/26/lync-ucwa-unified-communications-web-api/

UCWA C# ライブラリ

UCWA 2.0 は現時点でオフィシャルの C# ライブラリがありませんが、コミュニティエフォートで公開中です。

ソース: https://github.com/kenakamu/UCWA2.0-CS

以下手順でローカルにソースをダウンロードしておきます。

1. https://github.com/kenakamu/UCWA2.0-CS にアクセス。

2. 画面右側の 「Clone or download」より「Download ZIP」をクリック。

3. 保存した ZIP を右クリックし「プロパティ」を確認。ロックされている場合はアンロックする。

4. ZIP ファイルを任意のディレクトリに解凍。

Skype for Business 環境の準備

兎にも角にも Skype for Business がないと試せないので、Office 365 E3 の体験版を申し込みます。既に環境がある場合はスキップしてください。

1. https://products.office.com/ja-jp/business/office-365-enterprise-e3-business-software にアクセス

2. 「無料試用版」リンクをクリック。

image

3. ウィザードに従ってセットアップを進めます。大体 10 分くらいで完了します。

4. セットアップが完了したら、https://portal.office.com よりログインし、管理者アイコンをクリックします。

image

5. 検証するために、ユーザーを数名追加します。ユーザー | アクティブなユーザーよりユーザーの追加ボタンをクリックします。

image

6. 必須項目を埋めて、ユーザーを追加します。

image

7. 同様の手順でユーザーを数名追加しておきます。

8. Skype for Business にログインできるか試します。左上のワッフルメニューより「メール」を選択します。

image

9. 言語をタイムゾーンを選択してログインします。

10. 画面上部にある Skype アイコンをクリックして、Skype for Business ログインできるか確認します。

image

11. 画面右上のユーザーアイコンをクリックして、ステータスを変更して、正しく反映されることを確認します。

image

Azure AD への登録

UCWA を利用するためには、事前にアプリケーションを Azure AD へ登録する必要があります。

1. https://manage.windowsazure.com にログインします。Azure サブスクリプションが無い場合は、体験版をお試しください。

2. 「アプリケーション」タブをクリックします。

image

3. 画面下の「追加」ボタンをクリックします。

4. 「組織で開発中のアプリケーションを追加」をクリックします。

5. 任意のアプリケーション名を入力し、「ネイティブ クライアント アプリケーション」を選択して「次へ」をクリックします。

image

6. 任意の「リダイレクト URI」を入力して、「完了」をクリックします。

image

7. 「構成」タブをクリックして、「ClientId」をコピーします。後で利用するので保存しておきます。

image

8. 画面下方の「アプリケーションの追加」をクリックします。

image

9. 「Skype for Business Online」を選択して、「完了」ボタンをクリックします。

image

10. 「デリゲートされたアクセス許可」からすべての権限を選択します。

image

11. 「保存」ボタンをクリックします。

サンプルアプリケーション

今回は UWP (Universal Windows) アプリケーションに UCWA で Skype for Business の機能を載せてみます。

1. Visual Studio 2015 を起動し、「新しいプロジェクト」を選択します。

2. Visual C#  | Windows | ユニバーサルメニューより「空白のアプリ」を選択、任意の名前を付けて「OK」をクリックします。

image

3. 任意のターゲットバージョンを選択して、「OK」をクリックします。

NuGet パッケージの追加

1. プロジェクトを右クリックして、「NuGet パッケージの管理」をクリックします。

2. 参照より「Microsoft.IdentityModel.Clients.ActiveDirectory」(通称 ADAL) をインストールします。

image

3. 同様に JSON.NET も追加します。

プロジェクトの追加

1. ソリューションを右クリックして、追加 | 既存のプロジェクトを選択します。

2. 事前にダウンロードして解凍したフォルダにある UCWASDK.csproj を選択して追加します。

image

3. UCWAUWP プロジェクトの参照を右クリックして、参照を追加します。

image

4. UCWASDK ソリューションを選択して参照を追加します。

image

5. 一度コンパイルして問題がないか確認します。

認証用コードの追加

UCWA を利用するには Azure AD で OAuth 2.0 認証を利用しますが、ライブラリでは認証は各プログラムでやるようになっているため、以下の手順で認証のコードを追加します。

1. プロジェクトを右クリックして新しいクラスを追加します。ファイル名は TokenService.cs としておきます。

image

2. 以下のコードを貼り付け、環境に合うように定数を書き換えます。

public class TokenService
{
 public const string tenant = "ucwatest.onmicrosoft.com"; // i.e. "contoso.onmicrosoft.com";
 private static string clientId = "7b026311-5e71-4d3a-95d6-ef6a46d4434e"; // i.e. "4611b759-70fb-4465-953f-17949b15490a";
 private static Uri redirectUri = new Uri("http://localhost/ucwasample"); // i.e. http://localhost/app
 private static string sfbResourceId = "00000004-0000-0ff1-ce00-000000000000";
 private static string aadInstance = "https://login.microsoftonline.com/{0}";

 static public async Task<string> AquireAADToken(string resourceId = "")
 {
  if (string.IsNullOrEmpty(resourceId))
   resourceId = sfbResourceId;
  else
   resourceId = new Uri(resourceId).Scheme + "://" + new Uri(resourceId).Host;

  var authContext = new AuthenticationContext(string.Format(aadInstance, tenant));

  AuthenticationResult authenticationResult = null;

  try
  {
   authenticationResult = await authContext.AcquireTokenAsync(
   resourceId, clientId, redirectUri, new PlatformParameters(PromptBehavior.Auto, false));
  }
  catch (Exception ex)
  {
  }

  return authenticationResult.AccessToken;
 }
}

UCWA ライブラリの利用

UCWA ライブラリは、プロキシのインスタンスを作成後、必要なイベントを登録したら、後はサインインするだけです。

1. MainPage.xaml.cs を開き、以下の using を追加します。

using Microsoft.Skype.UCWA;
using System.Net.Http.Headers;
using Microsoft.Skype.UCWA.Models;
using Microsoft.Skype.UCWA.Enums;

2. クラスレベルのプロパティとして UCWAClient client; を設定します。

image

3. MainPage に以下のコードを追加します。

client = new UCWAClient();

4. client プロキシは UCWA を呼び出す際、毎回 SendingRequest イベントを発行します。ここで認証情報を付与できるよう、以下のコードを追加します。

client.SendingRequest += async (client, resource) => { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await TokenService.AquireAADToken(resource)); };

5. client プロキシは他の多くのイベントに対応しますが、今回は他のユーザーのプレセンス情報が変わった通知を受け取れるよう、以下のコードを追加します。

client.ContactPresenceUpdated += Client_ContactPresenceUpdated;

6. 次に初期化して、サインインするためのメソッドを追加します。SignIn にはいくつかの引数を渡せますが、ここではオンライン状態でサインインするようにしています。テナント名は変更してください。

private async void Initialize()
{
 await client.Initialize("ucwatest.onmicrosoft.com");
 await client.SignIn(availability: Availability.Online, supportMessage: true, supportAudio: false, supportPlainText: true, supportHtmlFormat: false, phoneNumber: "", keepAlive: true);
}

7. MainPage メソッドの最後で上記 Initialize メソッドを呼び出します。

8. ContactPresenceUpdated が発生した場合に実行される Client_ContactPresenceUpdated メソッドを追加します。中身は後で実装します。

private void Client_ContactPresenceUpdated(ContactPresence contactPresence, Contact contact)
{
}

アプリケーションのテスト実行

この時点で一度アプリケーションを実行してみます。

1. MainPage.xaml.cs の Initialize メソッド内にブレークポイントを貼ってからプログラムを実行します。

2. サインイン画面が表示されます。ユーザー名、パスワードを入力してログインします。

image

3. 無事サインインできれば成功です。アプリケーションを終了します。

ログインユーザーの情報取得

次にログインしているユーザーの情報を取得してみましょう。ユーザーの情報は client.Me よりプロパティまたはメソッドの実行で取得できます。今回は UI 側も触ります。

1. MainPage.xaml を開き既存の Grid 内に以下の XAMLを追加します。

<StackPanel Margin="30">
 <TextBlock x:Name="name"/>
 <TextBlock x:Name="title"/>
 <TextBlock x:Name="presence"/>
 <TextBlock x:Name="note"/>
</StackPanel>

2. MainPage.xaml.cs ファイルを開き、以下のコードを Initialize メソッドに追加します。

name.Text = client.Me.Name;
title.Text = client.Me.Title ?? "";
presence.Text = (await client.Me.GetPresencs()).Availability.ToString();
note.Text = (await client.Me.GetNote()).Message;

3. アプリケーションを実行して結果を確認します。以下の場合タイトルとメモが無いため空白ですが、名前をステータスが取れています。

image

まとめ

今回は一旦ユーザーでログインをしてデータを取得するところまでやってみました。次回はよりリッチな機能を追加してみます。

– 中村 憲一郎