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関連

    Presentation Translatorが公開されました。

    下記記事で紹介している「Microsoft Translator アド…

  2. Office関連

    UI Automationの参考資料

    VBAからUI Automationを扱う際に参考になりそうな資料への…

  3. Office関連

    オフィス祭り 2018 in 東京に参加しました。

    先日書いた下記記事の通り、9月15日(土)に品川にある日本マイクロソフ…

  4. Office関連

    SeleniumBasic(Selenium VBA)がMicrosoft Edgeに対応しました。…

    言わずと知れたWebブラウザーの自動制御ツール「Selenium」のV…

  5. Office アドイン

    Office Scripts機能によってWeb版Excelで操作の記録ができるようになりました。

    昨年からずっと待ち続けていた「Office Scripts」機能、つい…

  6. Office アドイン

    [Office用アプリ]マニフェストファイルをSharePointに配置する。

    今更になりますが、今回はマニフェストファイルをSharePoint上に…

コメント

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

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP