Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

大学の講義で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の作り方
Microsoft Cognitive Services の Text Translation API を(Node.js で)使ってみる
【Node.js】expressとbotkitを使って自分のURLを叩いたらBotがSlackにつぶやくサンプル【SlackBot】
 
 
以下が実際作成したコードです。

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以外からの要求をはじいたり、
英語以外のテキストだと翻訳しなかったり
したかったのですが...

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

gatosyocora
高知で大学生やっています。 VRに興味ありでVR学会認定VR技術者です
https://twitter.com/gatosyocora
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした