Rails|Amazon Translate の自動翻訳機能を実装する
目標
・Amazon Translateを利用して、自動翻訳機能を実装する。
・言語を選択し、「Translation」ボタンを押すと、ページが翻訳される。
開発環境
ruby 3.1.2p20
Rails 6.1.7.4
Cloud9
前提
AWSのアカウントを登録済み。
bootstrapを導入済み。
※Amazon Transate APIは有料のサービスなので、注意。(12ヶ月間のみ、制限付きで無料)
gemの導入
Gemfileに以下を記述。
# Amazon Translate
gem 'aws-sdk-translate'
以下のコマンドを実行。
$ bundle install
環境変数を設定
AWSのアクセスキー、シークレットアクセスキー、リージョンを確認する。
【上記3点の確認方法】
AWSのIAM(Identity and Access Management)で新しいユーザーを作成する。
「許可を追加」をクリックし、「TranslateFullAccess」ポリシーを追加する。
「セキュリティ認証情報」をクリックし、アクセスキーを作成する。
リージョンはAWSを開いている時のURLを確認する。
以下のように、環境変数を設定する。
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
AWS_REGION=xxxxx
環境変数をGitに上げない方法はこちらを参照。
コントローラの作成
pages_controllerを作成する。
$ rails g controller public/pages
class Public::PagesController < ApplicationController
include TranslationHelper
def translate_page
target_language = params[:target_language]
texts = params[:texts]
translated_texts = texts.map do |text|
translate_text(text, target_language)
end
render json: { translated_texts: translated_texts }
end
end
include TranslationHelper
TranslationHelperモジュールをインクルードしている。
target_language = params[:target_language]
ブラウザから送られてきたデータの中から、:target_language
というキーの値を取得して、target_language
変数に格納している。
texts = params[:texts]
翻訳したいテキストのリストをtexts
に格納。
translate_text(text, target_language)
この部分はTranslationHelperに定義されているメソッド。
render json: { translated_texts: translated_texts }
翻訳されたテキストのリストをJSON形式でブラウザに返している。
module TranslationHelper
def translate_text(text, target_language_code)
translate_client = Aws::Translate::Client.new(
region: ENV['AWS_REGION'],
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
)
response = translate_client.translate_text({
text: text,
source_language_code: "auto",
target_language_code: target_language_code
})
response.translated_text
end
end
translate_client = Aws::Translate::Client.new(...)
AWSのTranslateサービスを利用するためのクライアントオブジェクトを作成している。
response = translate_client.translate_text({})
上で作成したクライアントオブジェクトを使用して、実際にテキストの翻訳を行っている。
response.translated_text
翻訳のレスポンスから翻訳されたテキストを取得している。
$("#translate-page-btn").click(function(){
let selectedLanguage = $("#language-select").val();
let texts = $(".translatable-text").map(function(){
return $(this).text();
}).get();
let csrfToken = $("meta[name='csrf-token']").attr("content");
$.ajax({
url: "/translate_page", // サーバーのエンドポイント
method: "POST",
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', csrfToken)},
data: {
texts: texts,
target_language: selectedLanguage
},
success: function(response) {
// 翻訳されたテキストでページを更新
$(".translatable-text").each(function(index){
$(this).text(response.translated_texts[index]);
});
}
});
});
$("#translate-page-btn").click(function(){
IDがtranslate-page-btn
のHTML要素がクリックされた時の動作を定義。
let selectedLanguage = $("#language-select").val();
IDがlanguage-select
のHTMLの現在選択されている値を取得し、selectedLanguage
という変数に代入する。
let texts = $(".translatable-text").map(function(){...);
translatable-text
クラスを持つすべてのHTML要素のテキストを取得して、配列としてtexts
変数に格納。
let csrfToken = $("meta[name='csrf-token']").attr("content");
CSRFトークン(セキュリティのためのトークン)を取得している。このトークンは、後のAJAXリクエストでサーバーへ送信される際に使用される。
$.ajax({
非同期通信の機能。
url: "/translate_page",
サーバーへのリクエスト先URLを指定。
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', csrfToken)},
サーバーへのリクエストを行う前に、CSRFトークンをリクエストヘッダーに設定している。
success: function(response) {
サーバーからのレスポンスが成功した場合の処理を定義している。
$(".translatable-text").each(function(index){...});
サーバーから受け取った翻訳されたテキストを、ページ内の .translatable-text クラスを持つHTML要素にセットしている。
ルーティング
post 'translate_page', to: 'pages#translate_page'
ビューの作成
<!-- 翻訳言語選択のドロップダウン -->
<select id="language-select" class="mr-2 language-select">
<option value="ja">日本語</option>
<option value="en">English</option>
<!-- 他の言語オプションも追加 -->
</select>
<button id="translate-page-btn" class="btn btn-outline-secondary">Translation</button>
<%= javascript_pack_tag 'translation' %>
翻訳部分にクラスを追加
翻訳して欲しい部分に translatable-text
というクラスを追加する。
完成!
以上で、言語を選択して「Translation」ボタンをクリックすると、ページが自動翻訳される。
参考にさせていただいた記事
Discussion