Office アドイン

[Office用アプリ]Microsoft Translator APIを利用して選択文字列を翻訳する(クロスドメイン対応)。

[JavaScript API for Office]Microsoft Translator APIを利用して選択文字列を翻訳する。」で、Microsoft Translator APIを活用した翻訳アプリについて記事を書きましたが、Word 2013 RTMで改めて確認したところ動作しなくなっていました。


OAuth認証部分で躓いているので、どうやらクロスドメイン制約に引っ掛かってしまっているようです(前回の記事を書いたときには問題なかったので、IEやOfficeのアップデートが原因?)。

対処法として「Office 用アプリの開発のベスト プラクティス」に書かれている通り、マニフェストファイルにAppDomain要素を追加してみたのですが、

複数のドメインにまたがるブラウズ

可能であれば、複数のドメインにまたがるブラウズは避けます。oAuth を使用してあるサイトのリソースを別のドメインの別のサイトと共有する場合など、これが必要なシナリオでは、アプリのマニフェスト ファイルで AppDomains 要素と AppDomain 要素を使用して指定します。

Office 用アプリの開発のベスト プラクティス より

<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
  <Id>90a23a95-9db7-445c-9c71-faaccfe114bb</Id>
  <Version>1.0</Version>
  <ProviderName>きぬあさ</ProviderName>
  <DefaultLocale>ja-JP</DefaultLocale>
  <DisplayName DefaultValue="翻訳アプリ2" />
  <Description DefaultValue="Microsoft Translator APIを利用して選択文字列を翻訳します。"/>
  <IconUrl DefaultValue="http://officeimg.vo.msecnd.net/_layouts/images/general/office_logo.jpg" />
  <AppDomains>
    <AppDomain>https://datamarket.accesscontrol.windows.net</AppDomain>
    <AppDomain>http://api.microsofttranslator.com</AppDomain>
  </AppDomains>
  <Capabilities>
    <Capability Name="Document" />
    <Capability Name="Workbook" />
  </Capabilities>
  <DefaultSettings>
    <SourceLocation DefaultValue="http://localhost/apps/MSTranslator2.html" />
  </DefaultSettings>
  <Permissions>ReadWriteDocument</Permissions>
</OfficeApp>

結果は変わらずOAuth認証が上手くいきません。
仕方がないのでOAuth認証部分をPHPに任せることにします。

・MSTranslator.xml(マニフェストファイル)

<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
  <Id>26b8c84d-8891-4ca3-8b5f-189da663cfa7</Id>
  <Version>1.0</Version>
  <ProviderName>きぬあさ</ProviderName>
  <DefaultLocale>ja-JP</DefaultLocale>
  <DisplayName DefaultValue="翻訳アプリ" />
  <Description DefaultValue="Microsoft Translator APIを利用して選択文字列を翻訳します。"/>
  <IconUrl DefaultValue="http://officeimg.vo.msecnd.net/_layouts/images/general/office_logo.jpg" />
  <Capabilities>
    <Capability Name="Document" />
    <Capability Name="Workbook" />
  </Capabilities>
  <AppDomains>
    <AppDomain>https://datamarket.accesscontrol.windows.net</AppDomain>
    <AppDomain>http://api.microsofttranslator.com</AppDomain>
  </AppDomains>
  <DefaultSettings>
    <SourceLocation DefaultValue="http://localhost/apps/MSTranslator.html" />
  </DefaultSettings>
  <Permissions>ReadWriteDocument</Permissions>
</OfficeApp>

・MSTranslator.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script src="https://az88874.vo.msecnd.net/api/1.0/office.js"></script>
        <script>
            var target;
            Office.initialize = function (reason) {
                $(document).ready(function () {
                    Office.context.document.addHandlerAsync(Office.EventType.DocumentSelectionChanged, document_SelectionChange);
                });
            }
            function document_SelectionChange(eventArgs) {
                if ($("#action").attr("checked")) {
                    eventArgs.document.getSelectedDataAsync(Office.CoercionType.Text, function(asyncResult) {
                        if (asyncResult.status != Office.AsyncResultStatus.Failed) {
                            target = asyncResult.value;
                            execTranslate();
                        }
                    });
                }
            }
            
            $(function(){
                $("#result").click(
                    function() {
                        this.focus();
                        this.select();
                        clipboardData.setData("text", this.value);
                    }
                );
                
                $("#fromLng").change(function() {
                    if ($("#action").attr("checked")) {
                        execTranslate();
                    }
                });
                
                $("#toLng").change(function() {
                    if ($("#action").attr("checked")) {
                        execTranslate();
                    }
                });
            });
            
            function execTranslate() {
                if (target) {
                    fncTranslate($("#fromLng").val(), $("#toLng").val(), target);
                }
            }
            
            function fncTranslate(fromLng, toLng, str) {
                $("#result").val("ただいま処理中です。");
                $.getJSON(
                    "oauth.php",
                    function(data, status) {
                        var ah = "Bearer " + data.access_token;
                        $.ajax({
                            type: "GET",
                            url: "http://api.microsofttranslator.com/V2/Ajax.svc/Translate",
                            dataType: "jsonp",
                            data: {
                                appId: ah,
                                text: str,
                                from: fromLng,
                                to: toLng
                            },
                            jsonp: "oncomplete",
                            success: function(data, dataType){
                                $("#result").val(data);
                            },
                            error: function() {
                                $("#result").val("エラーが発生しました。");
                            }
                        });
                    }
                );
            }
        </script>
        <style>
            body {
                font-family:Arial,sans-serif;
                font-size:0.9em;
            }
            select,textarea {width:100%}
        </style>
    </head>
    <body>
        <input id="action" type="checkbox" title="チェックされている場合のみ翻訳が行われます。">動作
        <table>
            <tr>
                <td>翻訳元言語:</td>
                <td>
                    <select id="fromLng" title="翻訳元言語">
                        <option value="" selected>自動検出</option>
                        <option value="ar">アラビア語</option>
                        <option value="bg">ブルガリア語</option>
                        <option value="ca">カタロニア語</option>
                        <option value="zh-CHS">簡体字中国語</option>
                        <option value="zh-CHT">繁体字中国語</option>
                        <option value="cs">チェコ語</option>
                        <option value="da">デンマーク語</option>
                        <option value="nl">オランダ語</option>
                        <option value="en">英語</option>
                        <option value="et">エストニア語</option>
                        <option value="fi">フィンランド語</option>
                        <option value="fr">フランス語</option>
                        <option value="de">ドイツ語</option>
                        <option value="el">ギリシャ語</option>
                        <option value="ht">ハイチ語</option>
                        <option value="he">ヘブライ語</option>
                        <option value="hi">ヒンディー語</option>
                        <option value="mww">Hmong Daw</option>
                        <option value="hu">ハンガリー語</option>
                        <option value="id">インドネシア語</option>
                        <option value="it">イタリア語</option>
                        <option value="ja">日本語</option>
                        <option value="ko">韓国語</option>
                        <option value="lv">ラトビア語</option>
                        <option value="lt">リトアニア語</option>
                        <option value="no">ノルウェー語</option>
                        <option value="fa">ペルシャ語</option>
                        <option value="pl">ポーランド語</option>
                        <option value="pt">ポルトガル語</option>
                        <option value="ro">ルーマニア語</option>
                        <option value="ru">ロシア語</option>
                        <option value="sk">スロバキア語</option>
                        <option value="sl">スロベニア語</option>
                        <option value="es">スペイン語</option>
                        <option value="sv">スウェーデン語</option>
                        <option value="th">タイ語</option>
                        <option value="tr">トルコ語</option>
                        <option value="uk">ウクライナ語</option>
                        <option value="vi">ベトナム語</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>翻訳先言語:</td>
                <td>
                    <select id="toLng" title="翻訳先言語">
                        <option value="ar">アラビア語</option>
                        <option value="bg">ブルガリア語</option>
                        <option value="ca">カタロニア語</option>
                        <option value="zh-CHS">簡体字中国語</option>
                        <option value="zh-CHT">繁体字中国語</option>
                        <option value="cs">チェコ語</option>
                        <option value="da">デンマーク語</option>
                        <option value="nl">オランダ語</option>
                        <option value="en" selected>英語</option>
                        <option value="et">エストニア語</option>
                        <option value="fi">フィンランド語</option>
                        <option value="fr">フランス語</option>
                        <option value="de">ドイツ語</option>
                        <option value="el">ギリシャ語</option>
                        <option value="ht">ハイチ語</option>
                        <option value="he">ヘブライ語</option>
                        <option value="hi">ヒンディー語</option>
                        <option value="mww">Hmong Daw</option>
                        <option value="hu">ハンガリー語</option>
                        <option value="id">インドネシア語</option>
                        <option value="it">イタリア語</option>
                        <option value="ja">日本語</option>
                        <option value="ko">韓国語</option>
                        <option value="lv">ラトビア語</option>
                        <option value="lt">リトアニア語</option>
                        <option value="no">ノルウェー語</option>
                        <option value="fa">ペルシャ語</option>
                        <option value="pl">ポーランド語</option>
                        <option value="pt">ポルトガル語</option>
                        <option value="ro">ルーマニア語</option>
                        <option value="ru">ロシア語</option>
                        <option value="sk">スロバキア語</option>
                        <option value="sl">スロベニア語</option>
                        <option value="es">スペイン語</option>
                        <option value="sv">スウェーデン語</option>
                        <option value="th">タイ語</option>
                        <option value="tr">トルコ語</option>
                        <option value="uk">ウクライナ語</option>
                        <option value="vi">ベトナム語</option>
                    </select>
                </td>
            </tr>
        </table>
        <textarea id="result" title="クリックすると内容をクリップボードにコピーします。" rows="15">ここに結果が表示されます。</textarea>
    </body>
</html>

・oauth.php

<?php
    //********** 要変更 **********
    $client_id = "**********"; //クライアントID
    $client_secret = "******"; //顧客の秘密
    //****************************
    
    $url = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
    $scope = "http://api.microsofttranslator.com";
    $grant_type = "client_credentials";
    
    $ary = array (
        "grant_type"    => $grant_type,
        "scope"         => $scope,
        "client_id"     => $client_id,
        "client_secret" => $client_secret
    );
    $ary = http_build_query($ary, "", "&");
    $opt = array (
        CURLOPT_URL            => $url,
        CURLOPT_POST           => TRUE,
        CURLOPT_POSTFIELDS     => $ary,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE
    );
    $ch = curl_init();
    curl_setopt_array($ch, $opt);
    $res = curl_exec($ch);
    curl_close($ch);
    
    //jsonとして出力
    header("Content-Type: text/javascript; charset=utf-8");
    print $res;
?>

今度は上手くいきました。
アプリの動作が複数のドメイン間に跨る場合は、上記のようなプロキシスクリプトの利用も有効です。

Office用アプリ(apps for Office)の概要と開発方法前のページ

Office用アプリではalertやconfirmが使えない?次のページ

関連記事

  1. Office アドイン

    [Office用アプリ]法人登録する際の参考資料

    法人としてMicrosoft Seller DashboardでOff…

  2. Office関連

    [Excel]XLOOKUP関数でより簡単に値を検索できるようになりました!

    下記記事の通り、2019年8月末にVLOOKUP関数やHLOOKUP関…

  3. Office関連

    ちゃうちゃう! 2.0を操作するWordマクロ

    「テキスト比較ソフト「ちゃうちゃう!」がバージョンアップされました。」…

  4. Office関連

    [Office 2016]コマンド検索即実行、便利な「Tell Me」機能

    ※ 下記情報はOffice 2016 Preview版を元にしています…

  5. Office関連

    CDOを使ってGmail送信を行うVBAマクロ

    「VBA Gmail 送信」といったキーワード検索で、「Gmail A…

  6. Office関連

    [Excel Services ECMAScript]タイマーでグラフを描画する。

    タイマーで特定のセルの値を増やしていき、それに合わせてグラフを描画して…

コメント

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

PAGE TOP