Microsoft Translate API を用いた Slack 翻訳コマンドの実装

## モチベーション

留学生が多い研究室は多くあると思います。
しかし、学生みんな英語がペラペラなわけではありませんよね？汗

そして、言語の壁はチャット上でも存在します。
大事なことはちゃんと英語に訳しますが
些細なことを英語にいちいち訳すのはおっくですよね。

そこで、翻訳コマンドがあったら
チャット上の言語の壁が少しでも小さくなるのでは？
と思っていました。

## こんな感じ

<img width="360" alt="Screen Shot 2016-12-06 at 19.25.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/225b7b88-3f5c-e588-bd56-bd8ba41dc7c0.png">

英語は訳さない仕様です汗

## Microsoft Translate API

* [Microsoft Translator Text APIをNode.jsから使ってみる - Qiita](http://qiita.com/n0bisuke/items/350752978b16f4429b31)
* [Microsoft Translator APIを使ってみる - Qiita](http://qiita.com/kemayako/items/21fe36005e6e729aff77)

上記の記事を見つけていたのですが

<img width="1039" alt="Screen Shot 2016-12-06 at 19.33.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/46dd7b6a-5ebc-543a-7066-5ecbe957d06c.png">

もう DataMarket は終わってしまうようだったのでした。

そこで、 [Microsoft Cognitive Services の Translator API](https://www.microsoft.com/cognitive-services/en-us/translator-api) を使ってみることにしました。

<img width="1177" alt="Screen Shot 2016-12-06 at 19.40.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/26c576f9-1245-1db7-803b-553c85426b5f.png">

無料枠の制限は同じです。

### 登録とか

[ここ](http://docs.microsofttranslator.com/text-translate.html)見ながら適当に登録して、 `Translator Text API` の `Free` のものを適当にやりました。

<img width="907" alt="translate_api_overview.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/3344ae5f-060e-8aba-1fbe-5ac26c4db0b3.png">

### 鍵とかアクセストークンとか

#### スブスクリプションキー

<img width="636" alt="translate_api_key.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/a6cb5ecb-e9ef-68d4-48f2-769207fa60af.png">

`KEY1` と `KEY2` が何なのかよくわかりませんが、とりあえず `KEY1` だけでできました。

#### アクセストークン

http://docs.microsofttranslator.com/oauth-token.html

上の鍵と入れて `Try it out!` してみてください。
`Response Body` にトークンが返ってきてると思います。

<img width="1192" alt="Screen Shot 2016-12-06 at 20.30.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/3de82209-f803-7e6c-a02b-b328dce7caa0.png">

### API 一覧

http://docs.microsofttranslator.com/text-translate.html

あとはここを叩くだけです。

<img width="1194" alt="Screen Shot 2016-12-06 at 20.34.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/7decc37a-e0e9-7e32-2e38-e6ab1d0e06b6.png">


## Google Apps Script

### doPost

ウェブアプリケーションとして公開するために `doPost` 関数か、 `doGet` 関数を用意します。

```
function doPost(e) {
  if(e.parameter.token != SLACK_OUTGOING_TOKEN) return null;
  
  var command = e.parameters.text[0].split(" ");
  command.shift();
  var text = command.join(" ");
  var translated = translate(text);
  return postToSlack( SECRETARY, "#" + e.parameters.channel_name[0], translated);
}
```

### translate

実際に 翻訳APIを叩いているところです。
Detect も使って、テキストが何語なのかも判別しています。

```
function translate(text) {
  var subscription_key = "<さっきの鍵>";
  var token_url = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
  var token_options = {
   "method": "post",
   "headers": {
     "Accept": "application/jwt",
     "Ocp-Apim-Subscription-Key": subscription_key
   }
  };
  var access_token = UrlFetchApp.fetch(token_url, token_options).getContentText("UTF-8");
  
  var detect_url = "http://api.microsofttranslator.com/v2/Http.svc/Detect?text=" + encodeURIComponent(text);
  var translate_options = {
    "headers": {
      "Authorization": "Bearer " + access_token
    }
  };
  var language_xml = UrlFetchApp.fetch(detect_url, translate_options).getContentText();
  // <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">en</string>
  var language = XmlService.parse(language_xml).getRootElement().getText();

  var from = "ja";
  var to = "en";

  if (language.indexOf("ja") >= 0) {
    Logger.log("日本語です");
    from = language;
  } else if (language.indexOf("zh") >= 0) {
    Logger.log("中国語です");
    from = language;
  } else {
    Logger.log("英語です");
    return "You should read it in English. (-_-;";
  }
  
  var translate_url = "http://api.microsofttranslator.com/v2/Http.svc/Translate?from=" + from + "&to=" + to + "&text=" + encodeURIComponent(text);
  var translated_xml = UrlFetchApp.fetch(translate_url, translate_options).getContentText();
  var translated = XmlService.parse(translated_xml).getRootElement().getText();
  return translated;
}
```

日本語、中国語以外は全て英語としてしまうくそ仕様ですが。。

### 公開

公開したURLをSlackのoutgoing webhook に指定して、incoming webhook に翻訳後のテキストを返すようにしておけば出来上がりですね。

<img width="721" alt="Screen Shot 2016-12-06 at 20.45.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/dca6bcdc-50c7-df85-307e-4ff8d3fc477e.png">

## 所感

まあチャット言葉の翻訳は難しいですね。。。

<img width="390" alt="Screen Shot 2016-12-06 at 20.48.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/77c75116-1e37-a95e-7813-dcce3a9e35a3.png">