Google Cloud TranslationのAPIをローカルのNode.jsから試してみる

Google Cloud TranslationのAPIをローカルのNode.jsからアクセスしてみました。

[前回（といってももう1年半前ですが）](https://qiita.com/suzuki-navi/items/2647f1f65ef731d42aa4)Pythonで試しましたが、今回はNode.jsです。


# Cloud Translation APIを有効化

Google Cloudのコンソールにブラウザでアクセスして、使用するプロジェクトのCloud Translation APIを有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490207/fa4e81c5-b29b-cf96-0b19-393affc833a2.png)

ちなみに、有効化をせずにアクセスすると、以下のようなエラーがでました。

```
PERMISSION_DENIED: Cloud Translation API has not been used in project xxxxxxxxxxxx before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/translate.googleapis.com/overview?project=xxxxxxxxxxxx then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
```


# 認証設定

Google Cloud Platformのコンソール画面のIAM & AdminのService accountsというメニューから操作して、Create keyでキーを作成し、JSONファイルをダウンロードしておきます。そのJSONファイルを以下のように環境変数で指定しておきます。

```
$ export GOOGLE_APPLICATION_CREDENTIALS=$HOME/path/to/key.json
```


# パッケージインストール

```console
$ npm install @google-cloud/translate
```


# ソースコード


```javascript
const { TranslationServiceClient } = require("@google-cloud/translate").v3;

const projectId = "xxxxxxxx";
const location = "us-central1";

// 言語判定
async function detectLanguage(text) {
    const translationClient = new TranslationServiceClient();
    const req = {
        parent: translationClient.locationPath(projectId, location),
        content: text,
        mimeType: "text/plain",
    };
    const res = await translationClient.detectLanguage(req);
    let sourceLang = null;
    for (const elem of res) {
        if (elem == null) // なぜかnullがレスポンスに含まれる
            continue;
        return elem["languages"][0]["languageCode"];
    }
}

// 翻訳
async function translate(text, sourceLang, targetLang) {
    const translationClient = new TranslationServiceClient();
    const req = {
        parent: translationClient.locationPath(projectId, location),
        contents: [text],
        mimeType: "text/plain",
        sourceLanguageCode: sourceLang,
        targetLanguageCode: targetLang,
    };
    const res = await translationClient.translateText(req);
    for (const elem of res) {
        if (elem == null) // なぜかnullがレスポンスに含まれる
            continue;
        return elem["translations"][0]["translatedText"];
    }
}

async function sample(text) {
    console.log("original: " + text);

    // 言語の判定
    const sourceLang = await detectLanguage(text);

    // 翻訳
    for (const targetLang of ["en", "ja", "zh-TW", "zh-CN", "ko"]) {
        if (targetLang == sourceLang) // Target language can't be equal to source language. というエラーを防ぐため
            continue;
        const targetText = await translate(text, sourceLang, targetLang);
        console.log(targetLang + ": " + targetText);
    }

    console.log();
}

const texts = [
    "Hello, world!",
    "Firebase is Google's mobile platform that helps you quickly develop high-quality apps and grow your business.",
    "Vue是一套用于构建用户界面的渐进式框架。",
];

async function main() {
    for (const text of texts) {
        await sample(text);
    }
}

main().catch(err => {
    console.log(err);
});
```


# 実行結果

```console
$ node sample.js
```

```
original: Hello, world!
ja: こんにちは世界！
zh-TW: 你好世界！
zh-CN: 你好世界！
ko: 안녕, 세상!

original: Firebase is Google's mobile platform that helps you quickly develop high-quality apps and grow your business.
ja: Firebaseは、高品質のアプリをすばやく開発してビジネスを成長させるのに役立つGoogleのモバイルプラットフォームです。
zh-TW: Firebase是Google的移動平台，可幫助您快速開發高質量的應用程序並發展業務。
zh-CN: Firebase是Google的移动平台，可帮助您快速开发高质量的应用程序并发展业务。
ko: Firebase는 고품질 앱을 빠르게 개발하고 비즈니스를 성장시키는 데 도움이되는 Google의 모바일 플랫폼입니다.

original: Vue是一套用于构建用户界面的渐进式框架。
en: Vue is a progressive framework for building user interfaces.
ja: Vueは、ユーザーインターフェイスを構築するための進歩的なフレームワークです。
zh-TW: Vue是一套用於構建用戶界面的漸進式框架。
ko: Vue는 사용자 인터페이스 구축을위한 진보적 인 프레임 워크입니다.
```


# 参考

JavaScript用のGoogle Cloud Translation APIレファレンスはこちら。

- [TranslationServiceClient - Documentation](https://googleapis.dev/nodejs/translate/latest/v3.TranslationServiceClient.html)