Node.jsでコマンドラインツールをつくる


自己紹介

HAL大阪2回生のじゅんじゅんです。

普段は、学校とアルバイトで毎日を過ごしています。

よくイベントに出てるのでもしご一緒になることがあればお話ししましょう!

つくったもの

コマンドラインで他言語へ変換できるものをつくりました。

microsoftのtranslate apiを使わせていただきました。

実装

といっても、 @n0bisuke さんの記事をほぼパクってもらえれば大丈夫です。

Microsoft Translator Text APIをNode.jsから使ってみる

function getAccessToken(callback) {
    let body = '';
    let data = {
        'client_id': process.env.MS_TRANSLATE_ID,
        'client_secret': process.env.MS_TRANSLATE_SECRET,
        'scope': 'http://api.microsofttranslator.com',
        'grant_type': 'client_credentials'
    };

    let req = https.request({
        host: 'datamarket.accesscontrol.windows.net',
        path: '/v2/OAuth2-13',
        method: 'POST'
    }, (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,from,to, callback) {
    let options = 'from='+from+'&to='+to+'&text=' + qs.escape(text) +'&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);
    }
}

こんな感じですかね。

では、メインの部分をつくっていきます。

var text = process.argv[2] //変換するテキスト
var translate_type = process.argv[3] || "ja/en" // どのように変換するか

translate_type = translate_type.split("/");


getAccessToken((token) => {
  translate(token, text,translate_type[0],translate_type[1], (translated) => {
      console.log(translated);
  });
});

とても適当なコードですが動きます()

コマンドにする

さて。コマンドラインツールにするためにはコマンドにしないといけません。

これにはpackage.jsonを少しいじります。

{
  "name": "translate-command",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/konojunya/translate-command.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/konojunya/translate-command/issues"
  },
  "homepage": "https://github.com/konojunya/translate-command#readme"

みなさん、似たような感じの package.json をもっていると思います(僕のは npm init -y です)

ここに少し書き加えます。

"bin": {
  "translate": "bin/app.js"
}

この3行を追加してください!

なお、この時のkeyになってる部分がコマンド自体になるので、競合しないように、打ちやすいようにしてください。

さて、処理自体を書いているファイルを app.js として保存します。

全体の構造をみていきます。

今回つくった package.jsonapp.js の関係はこのようにしてください。

translate/
  - package.json
  - bin/
    - app.js

bin/app.js とします。そして、 translate の階層で

npm install -g としてください。

すると、 translate というコマンドが使えるようになっています。

あとは、好きなように翻訳を楽しんでください!

ただし、今回使用したAPIは200万文字までは無料ですが、その後は有料のようです。

お気をつけください。

あとがき

translate-command

GitHubにコードをあげています。

MSのAPI Keyだけ取得して環境変数にかいておけば、installationと書いている場所の通りにすれば動きます!

コマンドラインツールつくって、良きシェル生活を...