Posted at

オフショア開発するので翻訳botを作った

More than 1 year has passed since last update.

この記事はMonstar Lab, Inc. Advent Calendar 2016 16日目の記事です。

少し前にSIer(?)から、モンスター・ラボにやってきた岸田です。

とあるシステムの改修作業を細々やっていたと思ったら、いつの間にかオフショア開発を行っている会社にいました。

当社はベトナムや中国、バングラデシュなどをオフショア拠点とし、一緒にプロジェクトを進めています。

私は今、バングラデシュと開発を進めるプロジェクトを進めているサーバサイドエンジニアです。

オフショアとの開発はマネジメントや認識合わせが大変ですが、バングラデシュのエンジニア/PMたちはかなり優秀で、技術力もあり仕事に対しての責任感もあります。

日本で、自分たちだけで開発を行う以上に刺激的です。


が、

英語がつらい。


問題点


  • メンバー全員がストレスなく英語を読めるわけではない


    • 自分もそんなにスラスラ読めない

    • 返信に時間がかかる

    • コミュニケーションにオーバーヘッドが発生する



  • チャットなどで発言するのが億劫になる


    • ミスコミュニケーションの温床



よくない。

よし、Slackに翻訳bot作ろう。

ということで作りました。(細かい手順は書けてない


構成


  • AWS Lambda/API Gateway

  • Microsoft translator(翻訳)

  • Node.js


手順


  1. Microsoft Translatorに登録


    • 他に記事があると思うのでそちらで



  2. AWS Lambda functionを作成


    1. Blue printでmicroservice-http-endpointを選択

    2. function名とかを適当に

    3. zipをアップロード(今回は大したことないので、直接書いてしまった)

    4. Microsoft Translatorに使うclient_secretとかを環境変数に設定



  3. AWS API Gatewayの設定



    1. methodがデフォルトでANYになっていたので、POSTを設定

    2. Slackからはx-www-form-encodedでくるので、それの設定



  4. Slackの設定


    1. outgoingWebhookでAPI GatewayのURLを指定


    2. Trigger Word(s)toEn,toJaを設定



  5. Slackで使う


コード


index.js

'use strict';

const http = require('http');
const https = require('https');
const qs = require('querystring');

exports.handler = (event, context) => {
let blank = " ";
let texts = decodeURIComponent(event.text).replace(/\+/g, blank);
getAccessToken((token) => {
translate(token, texts, (translated) => {
context.done(null, { text: translated });
});
});
};

function getAccessToken(callback) {
let body = '';
var access_token = '';
let data = {
'client_id': process.env.環境変数名,
'client_secret': process.env.環境変数名,
'scope': 'http://api.microsofttranslator.com',
'grant_type': 'client_credentials'
};

let options = {
host: 'datamarket.accesscontrol.windows.net',
path: '/v2/OAuth2-13',
method: 'POST'
};

let req = https.request(options, (res) => {
res.setEncoding('utf8');
res.on('data', (chunk) => {
body += chunk;
}).on('end', () => {
let resData = JSON.parse(body);
callback(resData.access_token);
})
}).on('error', (err) => {
console.log(err);
});
req.write(qs.stringify(data));
req.end();
}

function translate(token, text, callback) {
let fromTo = text.indexOf('toEn') === 0 ? 'from=ja&to=en' : 'from=en&to=ja';
let options = fromTo + '&text=' + qs.escape(text.slice(4)) + '&oncomplete=translated';
let body = '';
let req = http.request({
host: 'api.microsofttranslator.com',
path: '/V2/Ajax.svc/Translate?' + options,
method: 'GET',
headers: {
"Authorization": 'Bearer ' + token
}
}, (res) => {
res.setEncoding('utf8');
res.on('data', (chunk) => {
body += chunk;
}).on('end', () => {
eval(body);
});
}).on('error', (err) => {
console.log(err);
});
req.end();

function translated(text) {
callback(text);
}
}


let texts = decodeURIComponent(event.text).replace(/\+/g, blank)

これはAPI Gatewayの設定でなんとかできる気がするんですが、ちょっと時間が...。

Microsoft Translatorから返ってくるのが、

translated("翻訳された文字列")だったのがびっくりしたぐらいで、ほかは簡単ですね。


はまったこと

context.done(null, { text: translated });

って書くところを

context.node(null, { text: translated });

と書いてるのに気付かなかったこと。

(つまり簡単でした


結果

こんな感じです。

こなん感じ

今日作ったのでまだ導入してません。

が、思ったより精度が低いです...。

スクリーンショット 2016-12-18 0.37.48.png

こんなのとかね。

Google translatorの方がいい感じに訳してくれるので、導入するか迷うところですね。

月の無料翻訳可能数にも制限があることですし。


大事なこと

英語を勉強しよう。

あとは、日本だけでなくいろいろな国や人とうまくコラボレートできるように試行錯誤することですね。

そして、投稿遅れてすみません🙇

本当は、KoltinでSpring Cloud Streamとか全部KotlinでWebアプリケーション作ってみたとかをやりたかったなぁ...