Firebase의 Cloud Functions에서 Google Cloud Translation을 사용해 보세요.

AWS EC2 인스턴스에서 Firebase 환경을 설정하여 Google Cloud Functions에서 Google Cloud Translation에 액세스해 보세요.

지난번은 로컬 Node.js 환경에서 Google Cloud Translation API에 액세스했지만 이번에는 Google Cloud Functions 환경에서입니다.

firebase 설치 및 인증 설정



Node.js를 설치했다고 가정합니다.
$ sudo npm install -g firebase-tools
$ firebase --version
9.8.0

설치 후 인증 설정이 필요합니다.
$ firebase login

이것은 대화형 명령입니다.

Google 인증을 위한 URL이 표시되므로 브라우저에서 동일한 방식으로 액세스합니다.

브라우저에서 승인하면 gcloud 인증 설정과 달리 http://localhost:9005/?...로 리디렉션됩니다. firebase login 커멘드를 로컬로 실행하고 있는 경우는, 커멘드가 9005번 포트를 일시적으로 대기하고 있으므로, 브라우저로부터 커멘드에 승인의 정보가 전해져, 마음대로 명령이 완료합니다.
firebase login 명령을 원격으로 실행하고 브라우저만 로컬인 경우에는 이 작업을 수행할 수 없습니다. 브라우저에 표시된 URL을 복사하고 원격으로 다른 터미널에서 연결하고 curl "http://localhost:9005/?..."를 실행합니다. curl 명령은 다음과 같은 HTML을 출력합니다. 이것으로 인증 설정이 완료됩니다.
      <h1>Firebase CLI Login Successful</h1>
      <p>You are logged in to the Firebase Command-Line interface. You can immediately close this window and continue using the CLI.</p>

firebase 프로젝트 만들기



먼저 빈 디렉토리로 이동합니다.
$ mkdir sample
$ cd sample

프로젝트 설정.
$ firebase init

또한 대화형 명령입니다.
Which Firebase CLI features do you want to set up for this folder?에 대해 Functions를 선택합니다.
Please select an option의 경우 Google Cloud 프로젝트에서 이미 Firebase를 사용한 적이 있다면 Use an existing project를 선택하십시오. Firebase를 처음 사용하는 Google Cloud 프로젝트인 경우 Create a new project를 선택합니다. 모두 Google Cloud 프로젝트가 이미 존재한다고 가정합니다.

그리고는, JavaScript or TypeScript 의 언어 선택등, 들었던 것을 대답합니다.

그러면 디렉토리 안에 소스 코드 등이 생성됩니다. .gitignore 도 생성되고 있으므로, 모처럼이므로,
$ git init

$ git add  -A

$ git ls-files
.firebaserc
.gitignore
firebase.json
functions/.gitignore
functions/index.js
functions/package-lock.json
functions/package.json

생성된 소스 코드는 이 7개의 파일과 같습니다.

Cloud Translation API 사용



Google Cloud 콘솔에 브라우저에서 액세스하여 사용할 프로젝트의 Cloud Translation API를 사용 설정합니다.



소스 코드 편집


functions/index.js 에 다음 코드를 썼습니다.
const functions = require("firebase-functions");
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) {
    const result = {};
    result["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);
        result[targetLang] = targetText;
    }

    return result;
}

exports.translation_demo = functions.https.onRequest(async (request, response) => {
  let query = request.query["q"];
  if (!query)
    query = "";
  sample(query).then(result => {
    functions.logger.info(result);
    response.send(result);
  }).catch(err => {
    functions.logger.info(err);
  });
});
functions/package.json 는 Google Cloud Translation용 라이브라이브를 추가합니다.
   "dependencies": {
     "firebase-admin": "^9.2.0",
-    "firebase-functions": "^3.11.0"
+    "firebase-functions": "^3.11.0",
+    "@google-cloud/translate": "*"
   },

배포



배포하기 전에 npm install가 필요합니다.
$ (cd functions; npm install)
firebase deploy 합니다. 이제 Google Cloud Functions가 생성됩니다. JavaScript의 소스 코드 중에 exports.translation_demo 라고 쓰고 있으므로, translation_demo 라는 이름의 Function 가 만들어집니다.
$ firebase deploy

(배포에 시간이 걸리는 것은 어떻게 되지 않을까・・・)

실행


$ curl -Ssf 'https://us-central1-xxxxxxxx.cloudfunctions.net/translation_demo?q=%E5%8F%91%E7%94%9F%E5%9C%A82021%E5%B9%B43%E6%9C%8823%E6%97%A5%E5%9F%83%E5%8F%8A%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4%E4%B8%8A%E5%8D%887%E6%97%B640%E5%88%86%EF%BC%8C400%E7%B1%B3%E9%95%BF%E7%9A%84%E9%95%BF%E8%8D%A3%E6%B5%B7%E8%BF%90%E9%9B%86%E8%A3%85%E7%AE%B1%E8%88%B9%E9%95%BF%E8%B5%90%E8%BD%AE%E5%9C%A8%E5%9F%83%E5%8F%8A%E8%8B%8F%E4%BC%8A%E5%A3%AB%E8%BF%90%E6%B2%B3%E6%90%81%E6%B5%85%E3%80%82' | jq .
{
  "original": "发生在2021年3月23日埃及标准时间上午7时40分,400米长的长荣海运集装箱船长赐轮在埃及苏伊士运河搁浅。",
  "en": "At 7:40 am Egypt Standard Time on March 23, 2021, the 400-meter-long Evergreen container ship Captain Ci was stranded on the Suez Canal in Egypt.",
  "ja": "2021年3月23日のエジプト標準時午前7時40分、長さ400メートルのエバーグリーンコンテナ船のキャプテンCiがエジプトのスエズ運河で立ち往生しました。",
  "zh-TW": "發生在2021年3月23日埃及標準時間上午7時40分,400米長的長榮海運集裝箱船長賜輪在埃及蘇伊士運河擱淺。",
  "ko": "2021 년 3 월 23 일 이집트 표준시 오전 7시 40 분, 400 미터 길이의 에버그린 컨테이너 선 선장 Ci가 이집트의 수에즈 운하에 좌초했습니다."
}

(고유명사의 번역이 잘 되지 않을 것 같지만, 괜찮은가・・・)

좋은 웹페이지 즐겨찾기