😸

Rails|Amazon Translate の自動翻訳機能を実装する

2023/09/11に公開

目標

・Amazon Translateを利用して、自動翻訳機能を実装する。
・言語を選択し、「Translation」ボタンを押すと、ページが翻訳される。

開発環境

ruby 3.1.2p20
Rails 6.1.7.4
Cloud9

前提

AWSのアカウントを登録済み。
bootstrapを導入済み。
※Amazon Transate APIは有料のサービスなので、注意。(12ヶ月間のみ、制限付きで無料)
https://hiromiick.com/decide-auto-translate-api/

gemの導入

Gemfileに以下を記述。

Gemfile
# Amazon Translate
gem 'aws-sdk-translate'

以下のコマンドを実行。

ターミナル
$ bundle install

環境変数を設定

AWSのアクセスキー、シークレットアクセスキー、リージョンを確認する。

【上記3点の確認方法】
AWSのIAM(Identity and Access Management)で新しいユーザーを作成する。
「許可を追加」をクリックし、「TranslateFullAccess」ポリシーを追加する。
「セキュリティ認証情報」をクリックし、アクセスキーを作成する。
リージョンはAWSを開いている時のURLを確認する。

以下のように、環境変数を設定する。

.env
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
AWS_REGION=xxxxx

環境変数をGitに上げない方法はこちらを参照。
https://zenn.dev/airiin/articles/d90bb1d6cdebd8#メールアドレスとアプリパスワードを環境変数に代入する

コントローラの作成

pages_controllerを作成する。

ターミナル
$ rails g controller public/pages
pages_controller.rb
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形式でブラウザに返している。

helpers/translation_helper
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
翻訳のレスポンスから翻訳されたテキストを取得している。

javascript/packs/translation.js
$("#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要素にセットしている。

ルーティング

routes.rb
  post 'translate_page', to: 'pages#translate_page'

ビューの作成

_header.rb
<!-- 翻訳言語選択のドロップダウン -->
    <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」ボタンをクリックすると、ページが自動翻訳される。

参考にさせていただいた記事

https://hiromiick.com/amazon-translate-with-rails/
https://hiromiick.com/decide-auto-translate-api/

Discussion