NCMBとMonaca、DeepL APIを使って翻訳アプリを作る（その2：翻訳処理とデータの保存）

NCMBとMonacaを使ってデモアプリを作ってみます。今回はDeepL APIを使った翻訳アプリです。翻訳結果をNCMBのデータストアに保存し、後で確認できるようにします。データストアにデータを保存したり、逆に取り出すのはよくあるケースなので、様々な場面で応用できるはずです。

[前回は画面の説明とSDKの導入まで紹介しました](https://qiita.com/goofmint/items/2af6873af4b6bb4350d1)。今回はDeepL APIを使った翻訳処理と、データをNCMBに保存するまでを解説します。

## コードについて

今回のコードは[NCMBMania/monaca_translation_app: MonacaとNCMB、DeepL APIを使った翻訳アプリです](https://github.com/NCMBMania/monaca_translation_app)にアップロードしてあります。実装時の参考にしてください。

## 翻訳処理について

翻訳画面を再掲します。翻訳するボタンを押すと `addTranslate` 関数が実行される仕組みです。日本語はテキストエリアに入力します。

```html
<div class="page-content">
	<div class="list no-hairlines-md">
		<form id="translation">
			<ul>
				<li class="item-content item-input">
					<div class="item-inner">
						<div class="item-title item-label">日本語</div>
						<div class="item-input-wrap">
							<textarea class="resizable" name="text" placeholder="翻訳するテキストを入力してください"></textarea>
						</div>
					</div>
				</li>
				${translatedText !== '' ?
				$h`
				<li class="item-content item-input">
					<div class="item-inner">
						<div class="item-title item-label">英訳</div>
						<div class="item-input-wrap">
							${translatedText}
						</div>
					</div>
				</li>
				`
				:
				''
				}
			</ul>
			<div class="block">
				<button class="button button-fill" @click=${addTranslate}>翻訳する</Button>
			</div>
		</form>
	</div>
</div>
```

![monaca-translation-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/cf6ec42f-3a5d-58ba-5b7e-a782b33b0beb.jpeg)


### JavaScript処理

Framework7の基本形として、JavaScriptは下記の中に書きます。今回はストア `$store` と画面更新用の `$update` 関数を使います。

```js
export default (props, { $store, $update }) => {
	// ここに記述
	return $render;
}
```

#### 画面表示で利用する変数

画面上では翻訳後のテキスト有無によって表示を変更しています。そのための変数を用意します。

```js
let translatedText = '';
```

#### 翻訳ボタンを押した後の処理

`addTranslate` 関数の内容です。まず入力値を取得して、それをDeepLにて英語に翻訳します。

```js
const addTranslate = async (e) => {
	e.preventDefault();
	// 入力値の取得
	const params = app.form.convertToData('#translation');
	// 翻訳実行（js/app.jsに定義）
	translatedText = await translationText(params.text);
	// 以下は後述
}
```

`translationText` 関数は `js/app.js` にて定義しています。契約状態によってURLが異なるので、変数化してあります。

```js
// DeepL実行用URL
const DEEPL_API_URL = 'https://api-free.deepl.com';

// DeepLを使ってテキストを翻訳する関数
const translationText = async (text, target_lang = 'EN-US') => {
  const res = await fetch(`${DEEPL_API_URL}/v2/translate`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      text,
      target_lang,
      auth_key: config.deepLAuthKey,
    })
  });
  const json = await res.json();
  return json['translations'][0]['text'];
}
```

翻訳されたテキストは画面表示に利用します。画面表示を更新した後、データをNCMBに保存します。

```js
// 画面を更新
$update();
// データをNCMBに保存する処理
await saveTranslate(params.text, translatedText);
```

#### NCMBのデータストアに翻訳結果を保存する

`saveTranslate` 関数の内容です。Translateはデータストアのクラス名（DBでいうテーブル名相当）になります。

```js
// NCMBにデータを保存する処理
const saveTranslate = (originalText, translateText) => {
	const Translate = ncmb.DataStore('Translate');
	const translate = new Translate;
	return translate
		.set('original', originalText)
		.set('translate', translatedText)
		.save();
}
```

#### ストアに反映

翻訳結果を保存したNCMBのデータはそのままストアに追加します。

```js
// ストアに追加
$store.dispatch('addTranslate', translate);
```

### 処理全体

`pages/translations.html` のJavaScriptは全体として、次のようになります。

```js
export default (props, { $store, $update }) => {
	let translatedText = '';
	// 翻訳ボタンを押した時の処理
	const addTranslate = async (e) => {
		e.preventDefault();
		// 入力値の取得
		const params = app.form.convertToData('#translation');
		// 翻訳実行（js/app.jsに定義）
		translatedText = await translationText(params.text);
		// 画面を更新
		$update();
		// データをNCMBに保存する処理
		const translate = await saveTranslate(params.text, translatedText);
		// ストアに追加
		$store.dispatch('addTranslate', translate);
	}

	// NCMBにデータを保存する処理
	const saveTranslate = (originalText, translateText) => {
		const Translate = ncmb.DataStore('Translate');
		const translate = new Translate;
		return translate
			.set('original', originalText)
			.set('translate', translatedText)
			.save();
	}
	
	return $render;
}
```

これでNCMBの管理画面にて、データストアにTranslateクラスができあがり、翻訳結果も保存されているのが確認できるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f5ab0830-6b52-dc67-fbed-4e899a199f1f.png)


## まとめ

NCMBを使うとクラウドデータベースへの保存がわずか数行で書けます。今回は使っていませんが、ACL（アクセス権限）も指定できます。ぜひ試してください。

[次回は保存したデータの取得と表示](https://qiita.com/goofmint/items/7058be7868dd763a1aa6)を行います。