de:code フォローアップ① Outlook メールアプリ での添付ファイル操作

こんにちは、奥田です。先日 de:code で Office アプリ開発 SP1 新機能についてのセッションを担当させていただきましたが、そのフォローアップ記事第1弾です。

少し前にリリースされた Office 2013 SP1 にて、Office 用アプリ開発においても新機能がたくさんあります。セッションでは、特に注目すべき変更点として Outlook のメールアプリについて、メインにお話させていただきました。

この記事では、その中で解説させていただいた添付ファイル操作について、サンプルコードの作成方法を補足させていただきます。

添付ファイル操作は、1.1 で追加された新しい API の利用で、ReadItem (項目の読み取り) 以上のアクセス許可レベルで可能となり、また OWA だけではなく、Outlook クライアントでもサポートされるようになりました。

参考:方法: Exchange サーバーから Outlook アイテムの添付ファイルを取得する

上記記事にあるサンプルコードを参考に、添付ファイルを操作するメールアプリを作成する際の参考手順です。
サーバーサイドコードの部分は、API コントローラーにより REST サービスとして用意したいと思います。

  ※  JSAPI 1.1 機能を利用するため、Microsoft Office Developer Tools for Visual Studio 2013 -  
       March 2014 Update パッケージ をインストールした環境で試していただけます。

1.VS でメールアプリプロジェクトを作成
     ●
メールの表示フォーム
     ●
[項目の読み取り] アクセス許可 (Manifest で設定)
     ●
メールボックスの要件セット 1.1 (Manifest で設定)

2.Web API コントローラー実装
     ●
[Webプロジェクト] を右クリック – [追加] – [Web API コントローラー クラス] を選択
         ※
メニューがでてこないときは、NuGet Microsoft ASP.NET Web API パッケージを入れるとよいかと

     ● クラス名を [***Controller] とします。
         ※ 
このあと、ASP.NET ルーティングでURLを構成するため、クラス名のおしりに、"Controller"
             とつけときます。

     ● コントローラークラス内の既定のコードを全部消して、次のコードを記述

    // Post アクションメソッド
    [HttpPost()]
    public string GetAttachment(AttachmentRequest request)
    {
      try
      {
        // EWS よびだしで、添付ファイル取得
        Attachment attachment = GetAttachmentFile
            (request.AttachmentId, request.AuthToken, request.EwsUrl);
        // 取得した添付ファイルをローカル保存 (パスは任意に変更を)
        System.IO.File.WriteAllBytes(@"c:\shared\"
            + attachment.AttachmentName, attachment.AttachmentBytes);
      }
      catch (Exception e)
      {
        return "エラー発生: " + e.Message + "\n\n" + e.StackTrace;
      }
      return "保存完了しました!";
    }

    // EWS よびだしを行い、添付ファイルを取得
    private Attachment GetAttachmentFile(string attachmentId,
        string authToken, string ewsUrl)
    {
      // GetAttachment SOAP リクエスト用に文字列作成
      string getAttachmentRequest =
          @"<?xml version=""1.0"" encoding=""utf-8""?>
              <soap:Envelope xmlns:xsi=""
http://www.w3.org/2001/XMLSchema-instance""
                xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
                xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/
              xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types"">
                <soap:Header>
                <t:RequestServerVersion Version=""Exchange2013"" />
                </soap:Header>
                    <soap:Body>
                    <GetAttachment
              xmlns=""
http://schemas.microsoft.com/exchange/services/2006/messages""
              xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types"">
                        <AttachmentShape/>
                        <AttachmentIds>
                        <t:AttachmentId Id=""{0}""/>
                        </AttachmentIds>
                    </GetAttachment>
                    </soap:Body>
                </soap:Envelope>";

      getAttachmentRequest = String.Format(getAttachmentRequest, attachmentId);

      // Web リクエストオブジェクトの作成
      HttpWebRequest webRequest = WebRequest.CreateHttp(ewsUrl);
      webRequest.Headers.Add("Authorization",
                        string.Format("Bearer {0}", authToken));
      webRequest.PreAuthenticate = true;
      webRequest.AllowAutoRedirect = false;
      webRequest.Method = "POST";
      webRequest.ContentType = "text/xml; charset=utf-8";
      byte[] bodyBytes
        = System.Text.Encoding.UTF8.GetBytes(getAttachmentRequest);
      webRequest.ContentLength = bodyBytes.Length;

      Stream requestStream = webRequest.GetRequestStream();
      requestStream.Write(bodyBytes, 0, bodyBytes.Length);
      requestStream.Close();

      // EWS リクエスト
      HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

      // XML ドキュメントをレスポンスから取得
      if (webResponse.StatusCode == HttpStatusCode.OK)
      {
        Stream responseStream = webResponse.GetResponseStream();

        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(responseStream);

        string fileName = xmlDocument.
            GetElementsByTagName("t:Name")[0].InnerText;
        byte[] bytes = Convert.FromBase64String(xmlDocument.
            GetElementsByTagName("t:Content")[0].InnerText);

        // レスポンス クローズ
        responseStream.Close();
        webResponse.Close();

        return new Attachment()
        {
          AttachmentBytes = bytes,
          AttachmentName = fileName
        };
      }
      return null;
    }

    public class Attachment
    {
      public byte[] AttachmentBytes { get; set; }
      public string AttachmentName { get; set; }
    }

    public class AttachmentRequest
    {
      public string AuthToken { get; set; }
      public string AttachmentId { get; set; }
      public string EwsUrl { get; set; }
    }

3.Global.asaxを作成し、API がよびだされるようルーティング規則を指定
    ●
[Webプロジェクト] を右クリック – [追加] – [グローバルアプリケーション クラス] を選択
         名前は Global のままにする

    ● Application_Start メソッド内に、次のコードを記述

          RouteTable.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

        (System.Web.Http と System.Web.Routing を using 追加)

4. メールアプリの表示フォームとして利用する html ファイルに、下記ソースを追加

      <button id="getAttachment">添付ファイル保存</button>

5.参照する js ファイルに、下記ソースを追加
     ●
Initialize メソッド内に、クリック操作追加

         $(‘#getAttachment’).click(getAttachment);

     ● 次のメソッド追加

   // 添付ファイル保存
    function getAttachment() {
        // 添付ファイル ID を JSAPI 利用して取得
        var attachmentId = Office.context.mailbox.item.attachments[0].id;
        // EWS EndPoint URL を JSAPI 利用して取得
        var ewsUrl = Office.context.mailbox.ewsUrl;
        // コールバックトークンを取得
        Office.context.mailbox.getCallbackTokenAsync(function (ar) {
            var attachmentData = {
                AuthToken: ar.value,
                AttachmentId: attachmentId,
                EwsUrl: ewsUrl
            };
            // コントローラークラス (サーバーサイドコード) の
            // GetAttachment を呼び出し (添付ファイルID、EWS URL、Token を渡す)
            sendRequest("コントローラー名/GetAttachment", attachmentData);
        });
    }

    // ヘルパー関数 コントローラークラス内の API 呼び出し
     function sendRequest(method, data) {
        $.ajax({
            url: ‘../../api/’ + method,
            type: ‘POST’,
            data: JSON.stringify(data),
            contentType: ‘application/json;charset=utf-8’
        }).done(function (data) {
            app.showNotification("成功", "指定の場所に保存しました。");
        }).fail(function (status) {
            app.showNotification(‘エラー’, JSON.stringify(status));
        });
     }

以上、コード内で行っている処理はセッション中に解説させていただいたとおりです。
参考にしていただければと思います。

奥田  うさぎ

広告

de:code フォローアップ① Outlook メールアプリ での添付ファイル操作」への1件のフィードバック

  1. ピンバック: de:code フォローアップ② Office アプリでの SharePoint Online アクセス (Common Consent Framework 利用) | クリエ・イルミネート ブログ

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中