Google Cloud Functions and Firebaseを使って
自動翻訳する機能ができるみたいですが
www.youtube.com
おお・・・すごいという所で止まっており
Angularでどうやってやるねん!!所が理解できなかったのですが
やっとサンプルも見つかったんで再現してみた
再現した内容は英語で入力した内容を
フランス語、スペイン語、アラビア語に変換する仕組みだった
- 1・Google Translation APIの許可をおこなう
- 2・firebaseのdatabaseのルールを変更する
- 3・angularのソースの修正
- 4・firebaseのfunctionをつくる
- 5・動作確認
- 6・参考URL
1・Google Translation APIの許可をおこなう
google デベロッパー コンソール
(https://console.cloud.google.com/?hl=ja)
に行ってプロジェクトを選択する
APIとサービスの有効化の画面が表示されたら
Translation
と入力する
クリックするとAPIの許可の画面が表示されるので
「有効化にする」をクリックする
*1・googleのサービスのfirebaseで変換をおこなうためAPI キーなどはメモを取る必要はありません
*2・ちなみにプロジェクトは決済ができるようにしないとできない
無料で遊べる範囲あるので注意が必要
2・firebaseのdatabaseのルールを変更する
firebaseのコンソール画面にいく
datebaseのルールを開してtranslationsを追加する
"translations": { ".read": true, ".write": true }
Angularのプロジェクト配下のdatabase.rules.jsonも修正する
*1・動画だとmessageというキーだったがサンプルだとtranslationsだったのでそちらに合わせている
3・angularのソースの修正
3-1・cliでベースをつくる
angularのプロジェクトのフォルダに移動して
angularのcliを使って
componetとserviceをつくる
ng g component text-translate ng g service text-translate/translate
下記のような形になるはず
3-2・app.moduleの修正の確認(自動なので・・・)
cliで作っているので
src/app/app.module.ts
import { TextTranslateComponent } from './text-translate/text-translate.component';
が追加になっていることを確認する
自分のプロジェクトの場合はroutingを使っているので
src/app/app-routing.module.tsの修正もおこなう
import { TextTranslateComponent } from './text-translate/text-translate.component'; ・ ・ { path: 'text-translate', component: TextTranslateComponent, },
3-3・サービスの修正
単純にfirebaseに保存しているだけ
src/app/text-translate/translate.service.ts
import { Injectable } from '@angular/core'; import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database'; @Injectable() export class TranslateService { constructor(private db: AngularFireDatabase) { } createTranslation(text: string): FirebaseObjectObservable<any> { // 翻訳するデータをjson形式で作成 const data = { 'english': text } // firebaseのデータ保存する const key = this.db.list('/translations').push(data).key return this.db.object(`translations/${key}`) } }
3-4・入力画面(テンプレート)の修正
src/app/text-translate/text-translate.component.html
<h1>翻訳機能テスト</h1> <textarea rows="8" cols="40" class="input" [(ngmodel)]="userText"></textarea> <button (click)="handleTranslation()" class="button is-primary">翻訳</button> <h3>フランス語</h3> {{ (currentTranslation | async)?.fr || defaultMessage() }} <h3>スペイン語</h3> {{ (currentTranslation | async)?.es || defaultMessage() }} <h3>アラビア語</h3> {{ (currentTranslation | async)?.ar || defaultMessage() }}
3-5・Componentの修正
src/app/text-translate/text-translate.component.html
import { Component } from '@angular/core'; import { TranslateService } from './translate.service'; @Component({ selector: 'text-translate', providers: [TranslateService], templateUrl: './text-translate.component.html', styleUrls: ['./text-translate.component.scss'] }) export class TextTranslateComponent { userText: string; currentTranslation; constructor(private translateSvc: TranslateService) { } handleTranslation() { this.currentTranslation = this.translateSvc.createTranslation(this.userText) } defaultMessage() { if (!this.currentTranslation) return "英語で入力して翻訳のボタンを押してください" else return "翻訳中です・・・" } }
参考にしたサイトだと
providers: [TranslateService],
がなかった・・・
そのため、下記のようなエラーがでた
ERROR Error: Uncaught (in promise): Error: No provider for TranslateService! Error: No provider for TranslateService!
このエラーっぽいので追加したら治った
https://stackoverflow.com/questions/36063823/angular2-no-provider-for-service-error
このエラーが意味がわからない所がまだ初心者を脱出していない証拠だな〜
4・firebaseのfunctionをつくる
angularのプロジェクトのフォルダに移動する
npm install -g firebase-tools
$ firebase login #vagrant $ firebase login --no-localhost
プロジェクトを選択してfunctionを選択する
$ firebase init
プロジェクトの配下に
functionsができるはず・・・できないなら
mkdir functionsでつくる
その配下に
index.jsとpackage.jsonがいるはず・・・
ないならつくって修正する
index.jsは
https://github.com/firebase/functions-samples/tree/master/message-translation
を参考にする
LANGUAGESの部分は変更した
functions/index.js
var functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); const request = require('request-promise'); const _ = require('lodash'); // List of output languages. const LANGUAGES = ['es', 'fr', 'ar', 'ja']; exports.translate = functions.database.ref('/translations/{translationId}').onWrite(event => { const snapshot = event.data; const promises = []; _.each(LANGUAGES, (lang) => { console.log(lang) promises.push(createTranslationPromise(lang, snapshot)); }) return Promise.all(promises) }); // URL to the Google Translate API. function createTranslateUrl(lang, text) { return `https://www.googleapis.com/language/translate/v2?key=${functions.config().firebase.apiKey}&source=en&target=${lang}&q=${text}`; } function createTranslationPromise(lang, snapshot) { const key = snapshot.key; const text = snapshot.val().english; let translation = {} return request(createTranslateUrl(lang, text), {resolveWithFullResponse: true}).then( response => { if (response.statusCode === 200) { const resData = JSON.parse(response.body).data; translation[lang] = resData.translations[0].translatedText return admin.database().ref(`/translations/${key}`) .update(translation); } else throw response.body; }); }
functions.config().firebase.apiKey}はfirebaseのapiキーなので自動的にはいる
functions/package.json
{ "name": "functions", "description": "Cloud Functions for Firebase", "dependencies": { "firebase-admin": "^4.2.1", "firebase-functions": "^0.5.7", "request": "^2.81.0", "lodash": "^4.17.4", "request-promise": "^4.2.1" }, "private": true }
パッケージのインストール
$cd functions $npm install
プロジェクトのフォルダに移動してデプロイする
$cd .. $firebase deploy --only functions === Deploying to 'angular-study-chat'... i deploying functions i functions: ensuring necessary APIs are enabled... i runtimeconfig: ensuring necessary APIs are enabled... ⚠ runtimeconfig: missing necessary APIs. Enabling now... ⚠ functions: missing necessary APIs. Enabling now... ✔ runtimeconfig: all necessary APIs are enabled i functions: waiting for APIs to activate... i functions: waiting for APIs to activate... i functions: waiting for APIs to activate... i functions: waiting for APIs to activate... i functions: waiting for APIs to activate... i functions: waiting for APIs to activate... ✔ functions: all necessary APIs are enabled i functions: preparing functions directory for uploading... i functions: packaged functions (1.34 KB) for uploading ✔ functions: functions folder uploaded successfully i starting release process (may take several minutes)... i functions: creating function translate... ✔ functions[translate]: Successful create operation. ✔ functions: all functions deployed successfully! ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/angular-study-chat/overview
5・動作確認
入力画面
ボタンを押すと
翻訳中と表示される
翻訳が完了すると自動的に反映される
firebaseのdatabaseも反映されていることが確認できる
6・参考URL
動画を見ながら再現しました
Text Translation with Firebase Cloud Functions onWrite and Angular 4 - YouTube