Amazon Translateを使ってみた＆自動翻訳付きチャットを作ってみた

Amazon Translateのプレビュー申請が先日通ったので、使ってみました。us-east-1（バージニア北部）で利用しています。

#Amazon Translateとは？
[公式ページ](https://aws.amazon.com/jp/translate/)へどうぞ。

#成果物
とにかく成果物が早く見たい方はこちらへ。

https://github.com/kojiisd/amazon-translate-chat-demo/tree/v0.1

# コンソールから使ってみる
とりあえずAWSコンソールから使ってみます。100万文字で15ドルの料金のようです。

![スクリーンショット 2018-01-13 16.05.42.png](https://qiita-image-store.s3.amazonaws.com/0/102769/f23bf416-ee1f-94f4-dc80-70b46ec9ad32.png)

選択できる言語は7つとまだ少なめですが、いずれすぐに日本語も追加されるでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/102769/43c26e66-b74b-2444-1a82-ba6822397827.png)

入力した文字がリアルタイムに翻訳されます。（日本語が選択できないので、文章を入れても自然な文章になっているのかは判断できませんがｗ）

![スクリーンショット 2018-01-13 16.08.49.png](https://qiita-image-store.s3.amazonaws.com/0/102769/0cf52395-bf6a-eb82-76d8-9906eb54e5c1.png)

# APIを使ってみる
ただこれだけだとなんの面白みもないので、自動翻訳をつけたようなチャットを作ってみたいと思います。

## 画面の準備
以前作成したiot-demo-deviceをベースに開発します。

https://github.com/kojiisd/aws-iot-demo-device/

とりあえずこんな感じの画面を組みます。

![スクリーンショット 2018-01-20 13.26.33.png](https://qiita-image-store.s3.amazonaws.com/0/102769/46e0e4eb-ef33-ab90-01ea-6711313f20e7.png)

|項目名|意味|
|:---|:---|
|Name|名前|
|Source Language|受信するメッセージの言語|
|Target Language|翻訳対象言語|
|Start Chat|チャット開始のためのボタン|
|Message|メッセージ|
|Send Message|メッセージ送付用ボタン|

最初は名前やメッセージ受信時の言語を選択しないとチャットを
スタートできないようにしています。
→メッセージをSubscribeする際に自身と同じ名前だったら翻訳しないようにするため。

画面下部の「Original」と「Translated」にメッセージのやりとりが記録されるように実装します。

## WebSocketにAWS IoTを利用する
チャットのやりとりをするために今回WebSocketを利用しますが、一から環境を用意するのが面倒なので、AWS IoTで手を抜きます。カスタマイズなどは特に気にせずデフォルトで設定してしまってOKです。

今回はこちらの記事と同じ設定をしました。

[Three.jsとAWSを連携させてIoTっぽいことしてみた](https://qiita.com/kojiisd/items/c072c76784eff98488f8)

AWS IoTは受信後のアクションが必要だったので、DynamoDBに履歴として登録する体で設定をしています。

## aws-sdkのフルビルド
この記事を書いている時の「v2.184.0」ではフルビルドをしないとAWS.Translateクラスが使えなかったため、公式ページを参考にビルドを実施します。

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/building-sdk-for-browsers.html

```sh
$ git clone git://github.com/aws/aws-sdk-js
$ cd aws-sdk-js
$ npm install
$ node dist-tools/browser-builder.js all > aws-sdk-full.js
```

## 翻訳部分を開発する
肝心の翻訳ですが、こんな感じのコードにします。事前にCredentialやEndpointなど必要な情報を設定しておく必要があります。なぜPromiseが必要かは後述します。

```js
AWS.config.credentials = new AWS.Credentials(cred.awsAccessKeyId, cred.awsSecretAccessKey);
  :
  :
function translate(message) {

  var params = {
    Text: message,
    SourceLanguageCode: srcLang,
    TargetLanguageCode: targetLang
  };

  var syncProc = new Promise(
    function (resolve, reject) {
      window.translator.translateText(params, function onIncomingMessageTranslate(err, data) {
        if (err) {
          reject("Error calling Translate. " + err.message + err.stack);
      }
        if (data) {
          resolve(data.TranslatedText);
        }
      });
    }
  );

  return syncProc;
}
```

## 翻訳語の文章の追加部分の開発
上述のtranslateメソッドを呼び出す部分ですが、メッセージ受信後のコールバックメソッドとなります。

```js
function onMessage(message) {
  var msgJson = JSON.parse(message.payloadString);
  var addingHtml = "<tr><td>" + msgJson.name + ": </td><td>" + msgJson.message + "</td>";
  if (msgJson.name == body.name) {
    addingHtml += "<td></td><td></td></tr>"
    $("#chatArea").prepend(addingHtml);
  }
  else {
    translate(msgJson.message).then(function (result) {
      addingHtml += "<td>" + msgJson.name + ": </td><td>" + result + "</td></tr>"
      $("#chatArea").prepend(addingHtml);
    }).catch(function(error){
      alert(error);
    });
  }
```

メッセージを受信した際、自身の名前と同じであれば翻訳は実施しないように処理をしています。

自分ではない人からのメッセージの場合translateメソッドを呼び出しますが、Translate APIにアクセスするタイミングで非同期処理となってしまうため、前述のPromiseでこの辺の処理の順番を制御しました。

# 実際の動き
画面を二つ用意して、それぞれ「kojiisd1」と「kojiisd2」でチャットを開始するようにします。設定はそれぞれ以下の通りとします。

||kojiisd1|kojiisd2|
|:---|:---|:---|
|Source Language|French|English|
|Target Language|English|French|


kojiisd1からは英語で話すようにし、kojiisd2からはフランス語で話をしてみます。

こんな感じで操作できました（ちょっとGIFのサイズ大きい）。

![amazon-translate-chat-demo3.gif](https://qiita-image-store.s3.amazonaws.com/0/102769/3a05bb7d-e146-bf68-73b9-587c0a70ede4.gif)

# まとめ
Amazonが提供する翻訳サービスなので、Pollyなど他のサービスとの連携も容易にできるようになると期待が持てます。これは電話会議などもAmazonが提供する翻訳サービスを使いながらリアルタイムに全て自動翻訳できる日が来そうな感じがして、期待大のサービスですね。