やること
Microsoft Translator テキスト API へ日本語の文字を送り、英語に翻訳されたデータを受け取る
JavaScript で実装する
流れ
- Microsoft Translator テキスト APIを有効化して、認証キーを取得する
- トークンを取得する
- トークンを使ってTranslator テキスト APIを叩く
- サンプルコード
- 参考情報
Microsoft Translator テキスト API を有効化して、認証キーを取得する
最初に、Translator テキスト APIを利用するため、Microsoft Azureから認証キーを取得する必要があります。詳細は以下に書かれています。
- Microsofut Azure アカウントを持っていない場合は、 https://azure.microsoft.com/ja-jp/ で Azure アカウントにサインアップする
- Azure アカウントに Microsoft Translator のサブスクリプションを追加する
- [すべてのリソース] メニューにアクセスしてサブスクリプションをクリックし、認証キーを取得する
下記の項目を設定します。
- Account Name
- 適宜名前をつけます。なんでもOK。
 
- サブスクリプション
- サブスクリプションを選択
 
- APIタイプ
- Cognitive サービスで使えるAPIを選択する。「Translator Text API」を選ぶ
 
- 価格
- 利用する価格帯を選ぶ。詳細は価格のページを参照。
- https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/
 
- リソースグループ
- Translator テキスト APIのリソースグループを選択。
 
- Resource Group Location
- ロケーションを選択
 
設定したら、リソースの詳細画面を開きます。
[Resource Management]の中にある[Keys]を選択すると、Translator テキスト APIを利用するためのAPIキーが表示されます。このキーを利用して、APIを叩きます。
Translator テキスト APIを利用するための流れは
- APIキーをつかってトークンを取得する
- 取得したトークンを使って、Translator テキスト APIを叩く
となります。
トークンを取得する
取得したAPIキーを使ってトークンを取得します。詳細は以下のドキュメントに書いています。
エンドポイント [https://api.cognitive.microsoft.com/sts/v1.0/issueToken] に対して
- APIキー
- Content Type
- Accept
の3つを指定してPOSTすると、トークンが取得できます。
crulを使う場合は
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/jwt' --header 'Ocp-Apim-Subscription-Key: 取得したAPIキー' 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken'
となります。
ドキュメントによると、取得したトークンの有効期間は10分と、かなり短めとなっているようです。ご注意ください。
トークンを使ってTranslator Text APIを叩く
トークンを利用して、Translator テキスト APIを叩きます。
Translator テキスト API のエンドポイントは、以下のドキュメントに説明があります。
単純に一語句、もしくは一文章を翻訳したい場合は [Translate]というエンドポイントをGETメソッドで叩きます。[Translate]を叩くためには、以下の3つの項目が必須となります。
- appid
- 送信する文字列は [Bearer] + [(半角スペース)] + [トークン] となる。トークンだけを投げてもうまくいかないため要注意。
 
- text
- 翻訳したい文字列を指定
 
- to
- 翻訳したい言語を指定。日本語に翻訳したい場合は [ja]。英語に翻訳したい場合は [en]となる。
 
サンプルコード
上記を踏まえて、簡単な翻訳アプリを作ってみました。Azure のアカウントをお持ちの方は
- APIキーを取得
- 下記のコードにAPIキーを記述して、htmlとして保存する
さえすれば、すぐ動くと思います。サーバーに上げずに、ローカルのPCでも動きました。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Microsoft Translator テキスト API で英訳を行うサンプルコード</title>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
  "use strict"
  $(function() {
// 文字が入力されたらイベント発火
    $("#word").change(function() {
// 認証トークンを取得するための関数 [getToken] を定義
// http://docs.microsofttranslator.com/oauth-token.html
      const getToken = function() {
        const defer = $.Deferred();
        $.ajax({
          url: 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken',
          type: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/jwt',
            'Ocp-Apim-Subscription-Key': 'Azureで取得したキーの文字列を記述します',
          },
        }).done(function(data) {
            const token = data;
            defer.resolve(token);
        });
            return defer.promise();
      };
// 関数 [getToken] 実行後、取得したトークンを 引き渡す
// フォームから入力したデータとともに、 Microsoft Translator テキストAPIへ送信
      $.when(getToken()).done(function(token) {
        const key = 'Bearer ' + token;
        const text = $("#word").val();
        const response = $.ajax({
          url: 'https://api.microsofttranslator.com/v2/http.svc/Translate',
          type: 'GET',
          data: {
            'appid': key,
            'Accept': 'application/xml',
            'text': text,
            'to': 'en',
          },
        async: false,
        })
// Translator テキスト APIを通じて取得したデータから、翻訳語が含まれるプロパティを取得
// replace関数でタグを除去し、翻訳データのみを抽出して表示する
        const data = response.responseText;
        const translation = data.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');
        $("#english").text(translation);
      })
    })
  })
 
</script>
</head>
<body>
  <h1>Microsoft Translator テキスト API サンプル</h1>
  <h2>入力データを英語に翻訳します。</h2>
  <input type="text" id="word" placeholder="何か入力してください" size="40">
  <div id="english"></div>
</body>
</html>
今回のサンプルプログラムでは毎回トークンを取得しています。トークンを取得後、Translator テキスト APIに値を渡すため、jQuery.Deferred とasync/false で、非同期処理ではなく同期処理を行いました。
エンドポイント [Translate] からの返り値はXMLデータとなるため、正規表現で翻訳語句のみを抜き出し、画面に表示しています。
毎回トークンを取得するのではなく
- 取得したトークンをsessionStorageに保存する
- トークンが有効期間内であれば再利用する
- 有効期限が切れた場合、トークンを再取得する
パターンも考えてみました。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Microsoft Translator テキスト API で英訳を行うサンプルコード</title>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
"use strict"
$(function() {
  // 文字が入力されたらイベント発火
  $("#word").change(function() {
// 現在の時刻をUNIX Time に変換して取得
    const now = new Date();
    const nowtime = now.getTime();
// 認証トークンを取得するための関数 [getToken] を定義
// http://docs.microsofttranslator.com/oauth-token.html
    const getToken = function() {
      const defer = $.Deferred();
// 現在時刻と、sessionStorageに保存されている時刻を比較
// sessionStorageに保存されているトークンが8分以内に発行されたものであれば、そのまままトークンを返す
// 8分以上経っている場合、もしくはトークンが存在しない場合、新規にトークンを取得。
// 取得したトークン、および取得時間をUNIX Time に変換したデータをJSON [datalist] に格納
// sessionStorage [tdata] にJSONを保存する
      
      const arr = JSON.parse(sessionStorage.getItem("tdata"));
      if (arr === null || arr.time + 1000 * 60 * 8 < nowtime) {
        $.ajax({
          url: 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken',
          type: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/jwt',
            'Ocp-Apim-Subscription-Key': 'APIキーを入力する',
          },
          async: false,
        }).done(function(data) {
          const datalist = {
            time: nowtime,
            token: data,
          }
          sessionStorage.setItem('tdata', JSON.stringify(datalist));
        });
      }
// sessionStorage に保存されたデータを変数 arr2 に格納
// JSONを文字列に変換後、トークンデータを引き出して翻訳用の関数にひきわたす
      const arr2 = JSON.parse(sessionStorage.getItem("tdata"));
      const token = arr2.token;
      defer.resolve(token);
      return defer.promise();
    };
// 関数 [getToken] 実行後、取得したトークンを 受け取る
// フォームから入力したデータとともに、 Microsoft Translator テキストAPIへ送信
    
    $.when(getToken()).done(function(token) {
      const key = 'Bearer ' + token;
      const text = $("#word").val();
      const response = $.ajax({
          url: 'https://api.microsofttranslator.com/v2/http.svc/Translate',
          type: 'GET',
          data: {
            'appid': key,
            'Accept': 'application/xml',
            'text': text,
            'to': 'en',
          },
          async: false,
        })
// Translator テキスト APIを通じて取得したデータから、翻訳語が含まれるプロパティを取得
// replace関数でタグを除去し、翻訳データのみを抽出して表示する
      const data = response.responseText;
      const translation = data.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');
      $("#japanese").text(translation);
    })
  })
})
</script>
</head>
<body>
  <h1>Microsoft Translator テキスト API サンプル</h1>
  <h2>フォームの入力データを英語に翻訳します。</h2>
  <input type="text" id="word" placeholder="何か入力してください" size="40">
  <div id="japanese"></div>
</body>
</html>
※サンプル実装なので、APIキーを直接コードに書いていますが、APIキーを第三者が認識できる状態にするのはとても危険です。ご注意ください。
参考情報
以下のドキュメントを参考にしました。
https://www.microsoft.com/ja-jp/translator/getstarted.aspx
https://www.microsoft.com/cognitive-services/en-us/documentation
http://docs.microsofttranslator.com/text-translate.html
積み残し
複数の文字列を同時翻訳する「TranslateArray」の利用がうまくいかないので要調査


