Uncategorized

Office 365 API : JavaScript Library for Cordova

Outlook REST API (以降の https://outlook.office.com または https://outlook.office365.com) は 2022/11/30 に終了予定です。今後は Microsoft Graph (統一エンドポイント) を使用してください。

環境 :
Visual Studio 2013 Update 2
Office 365 API Tools
Multi-Device Hybrid Apps for Visual Studio 2013

Office 365 API

(Skype API は こちら)

こんにちは。

今週は、前回書ききれなかった Office 365 API の JavaScript Library について記載します。

最近発表された調査結果でも iPhone、Android といったマルチデバイスに対応したアプリは、アプリ全体の 40 % を上回るそうですが、ここで使用する Apache Cordova は HTML / CSS / JavaScript による開発プラットフォームを提供することで、こうしたクロス デバイスのアプリ開発を実現します。
そして、最新の Visual Studio では「Multi-Device Hybrid Apps」という Cordova 用の開発環境が提供されています。

本日紹介する Office 365 API の JavaScript Library は、この Cordova での利用を想定したライブラリーです。

 

Setup

まず、Visual Studio に Cordova の開発環境をセットアップします。

Visual Studio 2013 に、Visual Studio 2013 Update 2Multi-Device Hybrid Apps for Visual Studio 2013、さらに、前回紹介した Office 365 API Tools – Preview もインストールしておいてください。(Multi-Device Hybrid Apps for Visual Studio 2013 をインストールすると、のちほど紹介するエミュレーターの関係で、Chrome ブラウザーも同時にインストールされます。)

補足 : Multi-Device Hybrid Apps for Visual Studio 2013 をインストールするには Windows 8.1 以上が必要です。 (残念ながら、Windows Server はダメみたいです。) CTP 3 で Windows 7, 8 や Windows Server による開発が可能になりました。(2014/08/05 追記)

補足 : 実行時に Android SDK に関連するエラーが表示される際は、野呂さんが書いてくれている「Visual Studio 2013 で Cordova で HelloWorld を作ってみよう (Multi-Device Hybrid Apps)」を参照してください。

 

Programming

では、早速、Office 365 API の JS Library を使った Cordova アプリを作成してみましょう。

まず、Visual Studio 2013 を起動し、[JavaScript] – [Multi-Device Hybrid App] から [Blank App] を選択して Cordova のプロジェクトを新規作成します。

Office 365 API Tools は Cordova の開発プロジェクトに統合されています。
プロジェクトを右クリックして、[追加] – [接続済みサービス] (Connected Services) を選択します。表示されるウィザードで、左ペインから [Office 365 APIs] を選択して [Sign in] リンクをクリックし、Office 365 のテナントにログイン (Sign in) します。

SignIn すると、Microsoft Azure Active Directory (Azure AD) への Application 追加や Permission 設定などをおこなうための画面が表示されますので、前回同様、Permission 設定をおこないます。
今回は Exchange Online から Mail の Read をおこなう簡単なアプリケーションを作成するので、下図の通り [Mail] の [Read User’s Mail] の Permission を設定します。

上記の設定をおこなうと、前回同様、裏側で、Microsoft Azure Active Directory (Azure AD) への Application 追加と Permission 設定がおこなわれます。
またこの設定と同時に、プロジェクトに、o365adal.js, exchange.js など必要なライブラリーが挿入されます。(下図)

補足 : 開発者自身で必要なライブラリーのロードだけをおこないたい場合には、NuGet から Microsoft Office 365 APIs Client Libraries for JavaScript (Microsoft.Office365.ClientLib.JS) をインストールしてください。

Cordova プロジェクトでは、まず、プログラミングを開始する前に、config.xml を編集して、使用する機能に応じた Plugins (Capability) の設定をおこないます。
Office 365 API を使用する場合は、前回解説したように Web Browser 用のコンポーネント (Android の WebView、iOS の UIWebView など) が必要となるため、今回のプロジェクトでは下図の [InAppBrowser] の Plugin (Capability) が必要ですが、実は、上述の Office 365 API Tools の設定により、この設定が自動的におこなわれるので、追加の設定は不要です。

通常の開発だと、jquery mobile, AngularJS など好みの JavaScript ライブラリーやフレームワークと組み合わせて UI デザインなども行いますが、今回は Office 365 API を紹介することが目的なので、jquery も AngularJS も使用せずバニラな感じで作ってみましょう。(なお、de:code の私のデモでは、見栄えを考慮して bootstrap を使用しました。bootstrap を使えば、下記サンプルのような table の列幅の面倒な制御なども不要です。)

今回のサンプルでは、「Get Mails !」というボタンを配置して、このボタンを押したら Office 365 にログインをおこなって、Exchange Online から Inbox の Mail を取得して table に挿入します。下記のコードになります。

index.html

<!DOCTYPE html><html><head>  <meta charset="utf-8" />  <title>Office365APIJSSample</title>  <link href="css/index.css" rel="stylesheet" />  <script src="services/office365/scripts/InAppBrowserOverride.js"></script>  <script src="services/office365/settings/settings.js"></script>  <script src="services/office365/scripts/utility.js"></script>  <script src="services/office365/scripts/o365auth.js"></script>  <script src="services/office365/scripts/exchange.js"></script></head><body>  <h4>Get all inbox e-mail<input id="getInboxBtn" type="button" value="Get Mails !" />  </h4>  <table id="msgTbl" style="table-layout: fixed;" border="1"><colgroup>  <col class="w_from" />  <col class="w_subject" /></colgroup><thead>  <tr><th>From</th><th>Subject</th>  </tr></thead><tbody></tbody>  </table>  <!-- Cordova reference, this is added to your app when it's built. -->  <script src="cordova.js"></script>  <script src="scripts/index.js"></script></body></html>

index.js

var O365APIJSSample;(function (O365APIJSSample) {  "use strict";  (function (Application) {function initialize() {  document.addEventListener('deviceready', onDeviceReady, false);}Application.initialize = initialize;function onDeviceReady() {  document.addEventListener('pause', onPause, false);  document.addEventListener('resume', onResume, false);  // button click event  var getInboxBtn = document.getElementById("getInboxBtn");  getInboxBtn.addEventListener("click", getInbox);}function onPause() {}function onResume() {}function getInbox() {  var ctx = new O365Auth.Context();  ctx.getIdToken('https://outlook.office365.com/').then((function (id_token) {var client = new Microsoft.OutlookServices.Client(  'https://outlook.office365.com/api/v1.0',  id_token.getAccessTokenFn('https://outlook.office365.com'));client.me.messages.getMessages().fetch().then(function (items) {  items.currentPage.forEach(function (item, idx, arr) {var msgTbl = document.getElementById("msgTbl");var row = msgTbl.insertRow(-1);var cel1 = row.insertCell(0);cel1.appendChild(document.createTextNode(item.sender.emailAddress.address));cel1.setAttribute("nowrap", "nowrap");var cel2 = row.insertCell(1);cel2.appendChild(document.createTextNode(item.subject));  });}, function (reason) {  // o365 api error  // see reason._message ...});  }).bind(this), function (reason) {// authentication failed// see reason._message ...  });}  })(O365APIJSSample.Application || (O365APIJSSample.Application = {}));  var Application = O365APIJSSample.Application;  window.onload = function () {Application.initialize();  };})(O365APIJSSample || (O365APIJSSample = {}));//# sourceMappingURL=index.js.map

 

Debug & Execute

F5 ボタンを押してデバッグ実行をおこなってみましょう。

Cordova では Local Machine, Simulator などを使用したデバッグが可能ですが、プロジェクトの既定の設定では、Ripple という Chrome を使った Android Emulator が起動します。(この設定は、プロジェクトのプロパティで構成できます。必要な Emulator をインストールしておいてください。)
下図のような [Get Mails !] ボタンの付いた画面が Chrome 上に表示されるので、このボタンを押します。すると、いつものように、Office 365 の SignIn 画面が表示され、SignIn を完了すると Exchange Online から Inbox メールが検索されて、下図の通り結果が表示されるでしょう。

補足 : iOS 用アプリとしてデバッグする場合には、OSX 用の vs-mda-remote が使用できます。

なお、Ripple のエミュレーターの場合、SignIn の際に Chrome の別画面がポップアップするかと思いますが、実機では、上述で plugin されていた Cordova の InAppBrowser を使用して、デバイス上にログイン画面が表示されます。

また、ログインに成功すると、利用者に Exchange の Mail の Read 権限を付与するための Consent UI (下図) が表示されるでしょう。(この Consent UI の詳細については「Azure Active Directory の Common Consent Framework」を参照してください。)

なお、2 回目以降、このアプリケーションにアクセスしても Login (SignIn) 画面は表示されません。理由は、JavaScript Library で、取得した access_token, refresh_token などの情報を localStorage に保持しているためです。
このため、再度、ログイン画面を表示して検証 (デバッグ) をおこなう場合は、以下のプログラムを実行し、この Cordova の cache (localStorage) を削除しておきましょう。

window.localStorage.clear();

 

typescript との better together

上記のプロジェクトで scripts/typing フォルダーを見てください。下図のように、o365adal.d.ts、aadgraph.d.ts、exchange.d.ts などが入っているのが確認できますね。
そうです、Office 365 API の JavaScript Library は、typescript の定義ファイルも提供しています。(インテリセンスがばっちり使えます。)

例えば、上記の index.js を削除して、以下の index.ts ファイルに変えてみてください。
実行すると、ビルドの際に tsc.exe (typescript のコンパイラー) が動作して index.js ファイルを生成し、上記と同様の結果となるでしょう。

index.ts

module O365APIJSSample {  "use strict";  export module Application {export function initialize() {  document.addEventListener('deviceready', onDeviceReady, false);}function onDeviceReady() {  document.addEventListener('pause', onPause, false);  document.addEventListener('resume', onResume, false);  var getInboxBtn = document.getElementById("getInboxBtn");  getInboxBtn.addEventListener("click", getInbox);}function onPause() {}function onResume() {}function getInbox() {  var ctx = new O365Auth.Context();  ctx.getIdToken('https://outlook.office365.com/').then((function (id_token: O365Auth.Token) {  var client = new Microsoft.OutlookServices.Client('https://outlook.office365.com/api/v1.0',id_token.getAccessTokenFn('https://outlook.office365.com'));  client.me.messages.getMessages().fetch().then(function (items) {  items.currentPage.forEach(function (item, idx, arr) {var msgTbl =  document.getElementById("msgTbl");var row =  msgTbl.insertRow(-1);var cel1 =  row.insertCell(0);cel1.appendChild(document.createTextNode(item.sender.emailAddress.address));cel1.setAttribute("nowrap", "nowrap");var cel2 = row.insertCell(1);cel2.appendChild(document.createTextNode(item.subject));  });}, function (reason) {  // o365 api error  // see reason._message ...});}).bind(this), function (reason) {  // authentication failed  // see reason._message ...});};  }  window.onload = function () {Application.initialize();  }}

これは Office 365 API のメリットではなく typescript そのものの一般的メリットですが、private メソッドや public メソッドなど型の情報が明確なので、いろいろと恩恵を受けることができます。
例えば、上記の for loop の箇所は、実は、JavaScript を使った場合、以下のような誤った書き方も可能です。(_data は undocumented なメンバーですので、使わないようにしてください。) しかし、typescript では、_data などは private メンバーなので error になります。

. . .for (var i = 0; i < items._data.length; i++) {  var msgTbl = document.getElementById("msgTbl");  var row = msgTbl.insertRow(-1);  var cel1 = row.insertCell(0);  cel1.appendChild(document.createTextNode(items._data[i]._Sender._EmailAddress._Address));  cel1.setAttribute("nowrap", "nowrap");  var cel2 = row.insertCell(1);  cel2.appendChild(document.createTextNode(items._data[i]._Subject));}. . .

また、型が明示的に定義されているため、下図のように、JavaScript のときには Intellisense が表示されなかった箇所 (戻り値の型が不定な箇所) でも、追加の設定をする必要なく Intellisense が表示されます。まるで C# でコードで書いているかのようにプロパティを見ながらどんどんコードを書いていくことができますね。

 

このように、Office 365 API においても、JavaScript を使用せず、むしろ typescript でコードを記述するほうが、開発生産性やコード品質などが飛躍的に向上すると思いますので、是非活用してみてください。

Categories: Uncategorized

Tagged as:

Leave a Reply