LINEで投稿された英語の日本語訳をSlackのチャンネルに投稿する

#はじめに
大学の講義でLINEグループに英語による指示が来ることがあり、
その度に友人がGoogle翻訳を使ってその内容を訳していました。
面倒くさそうだということで自動化しました。

友人とはSlackのチームで議論などをおこなっているため、
そちらに日本語訳したものを投稿しています。

**※Node.jsとHeroku初心者が書いているのでまだへなちょこなコードです。
　進捗上がり次第、随時更新します。**

# 翻訳WebAPIの開発

## 翻訳はどうするか問題
開発するにあたって
　1. LINEで英語のメッセージを取得する
　2. 日本語へ翻訳する
　3. Slackへ投稿する
という過程が必要です。

「1と3はbotを使えばいいだろう」という憶測で、ネックなのは2の翻訳...
「翻訳なら天下のGoogle翻訳だ」ということで調べてみると**『有料』**の2文字...
なんとか無料で使える翻訳APIはないのかと調べると
ありました**『Microsoft Text Translation API』**が！
これは**月に200万文字まで**は無料で利用できるそうです。
非常にありがたい(^人^)

##コーディング

何を使うかも決まったところで
先人様の記事を参考にしながら開発を進めました。
[LINE Messaging APIを使用したLINE Botの作り方](http://whippet-818.hatenablog.com/entry/2017/02/07/004558)
[Microsoft Cognitive Services の Text Translation API を(Node.js で)使ってみる](https://qiita.com/albno273/items/c160d435ee3a2cc3fe5f)
[【Node.js】expressとbotkitを使って自分のURLを叩いたらBotがSlackにつぶやくサンプル【SlackBot】](https://qiita.com/Kurowasi/items/a6498e35abbf7b77f47e)
　
　
以下が実際作成したコードです。

```javascript:index.js
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');

const app = express();

// 投稿先slackの指定
const SLACK_TOKEN = '<Slack BotsのAPIトークン>';
const SLACK_CHANNEL = '<Slackの投稿先チャンネル名>'; // ex) general

// Slackbotの準備
const botkit = require('botkit');
const controller = botkit.slackbot();
const bot = controller.spawn({
  token: SLACK_TOKEN
}).startRTM(function(err, bot, payload) {
  if (err) throw new Error('Could not connect to Slack');
});

app.set('port', (process.env.PORT || 5000));

// JSONの送信を許可
app.use(bodyParser.urlencoded({extended: true}));
// JSONのパースを楽に(受信時)
app.use(bodyParser.json());

// lineで受け取り、翻訳したものをslackへ
app.post('/line', function(req, res, next){
    res.status(200).end();

    for (var event of req.body.events){
      　 // LINEからテキストメッセージが送られてきた場合
        if (event.type == 'message'){

          // Microsoft Translatorで翻訳
          getAccessToken(function (err, token) {
            if (!err) {
              translate(token, event.message.text, (err, translated) => {
                if (!err) {
                    // Slackに投稿する
                    bot.say({
                      channel: SLACK_CHANNEL,
                      text: translated,
                      username: '<Slackへ投稿するボット名(任意なものでOK)>',
                      icon_url: ''
                    });
                }
              })
            }
          });

        }
    }
});

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});


// Microsoft Text Translation APIのアクセストークンを取得
function getAccessToken(callback) {
  let headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/jwt',
    'Ocp-Apim-Subscription-Key': '<Azureで作成したアカウントのKEY>'
  };
  let options = {
    url: 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken',
    method: 'POST',
    headers: headers,
    json: true
  };

  request(options, function (err, res) {
    if (err) {
      console.log(err);
      callback(err, null);
    } else
      callback(null, res.body);
  });
}

// 翻訳 (英語 -> 日本語)
function translate(token, text, callback) {
    let base_url = 'https://api.microsofttranslator.com/v2/http.svc/Translate',
        appid = 'Bearer ' + token,
        from = 'en',
        to = 'ja';

    let url = base_url + '?appid=' + appid +
                '&text=' + text + '&from=' + from + '&to=' + to;
    let headers = {
        'Accept': 'application/xml'
    };

    let options = {
        url: encodeURI(url),
        method: 'get',
        headers: headers,
        json: true
    };

    request(options, function (err, res) {
        if (err) {
            console.log(err);
            callback(err, null);
        } else
            callback(null, res.body.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, ''));
    });

}
```
　
これでLinebotを招待したグループで投稿されたメッセージは
日本語訳されてSlackの指定のチャンネルに投稿されるようになりました。

#最後に
本当はasyncとか使ったり、
linebot以外からの要求をはじいたり、
英語以外のテキストだと翻訳しなかったり
したかったのですが...


まだまだ未完成です...