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
- Office 365 API 入門
- HTML ハイブリッド アプリでの使用 (JavaScript for Cordova)
- Web フロントエンド (JavaScript) での使用 (CORS)
- PHP, Node.js からの使用
- Outlook REST API を使った開発 (Outlook.com 対応)
- Outlook REST API での通知 (Webhook) ・同期 (Sync) の処理
- OneDrive API を使った開発
- OneDrive API での通知 (Webhook)・同期 (Sync) の処理
- Yammer 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 2、Multi-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