18
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DeepLで翻訳機能を実装する

Last updated at Posted at 2023-12-06

【概要】


翻訳機能のAPI実装になります。
今回は、DeepLでの実装になりますので、Google翻訳APIでない点についてご留意ください。
併せて、今回はDeepLのGemを使用しますので、詳細は、下記からご確認お願いします。

【環境】


・Rails:3.2.2
・Ruby :7.0.8
・DeepL

【導入背景】


自身のアプリでレシピを取得するために、EdamamsAPIという海外のAPIを導入しました。
しかし、英語でリクエストを送信しない場合は、取得時に失敗するという問題点がありました。

EdamamsAPIについては、下記になります。詳細が気になる方は下記の記事を参照してください。

【Google翻訳APIとの相違点】


以上から、翻訳機能の実装に至ったのですが、翻訳機能について調査を行った結果、GoogleAPIDeepLが候補に上がりました。相違点は下記になります。

Google翻訳API DeepL
メリット サポート言語が豊富・無料の文字数が多い Google翻訳より翻訳精度が高い
デメリット 翻訳制度が悪い 無料の文字数が少ない

翻訳精度に関しては、下記のサイトが参考になるかと思います。

今回の実装では、リクエストの数を考えた時にDeepLの無料枠で問題ない範囲でしたので、後者で実装することにいたしました。

【DeepL側での準備】


ここからは実装フェーズになります。
まずは、下記から、ログインして登録などを行なってください。また、不明点がある場合、下記の手順書を参考にしてください。

【手順書】
https://auto-worker.com/blog/?p=5030

以上が、DeepL側で実装する内容になります。ここからは、ソースを編集していきます。

【DeepLの実装_SRC編】


上記で取得した認証keyの情報を使用して、APIを実施塩ていきたいと思います。なお、今回の実装ではdotenv-railsのgemを使用して実装しておりますが、credentialで実装していたただいても構いません。

【DeepLの実装_下準備】


1.dotenv-railsのgrm取得

gemfile
gem 'dotenv-rails'
ターミナル
bundle install

2.envファイルに認証KEYの情報をセット

ターミナル
touch .env //.envファイルを作成
ターミナル
DEEPL_KEY='先ほど取得したDeepL-keyの内容'

3.deeplのgemを取得

gemfile
gem 'deepl-rb', require: 'deepl'
ターミナル
bundle install

4.httpclient通信するためのgemを取得

gemfile
gem 'httpclient'
ターミナル
bundle install

【DeepLの実装】


ここからが、実装になります。

app/controllers/edamams_controller.rb
class EdamamsController < ApplicationController
  skip_before_action :require_login, only: %i[index]

  require 'httpclient' # HTTP通信を行うためのライブラリ(API使用時に必要)
  require 'cgi' 
  require 'deepl' # gemを使用するため、ここで読み込み処理をかける

  def index
    query = params[:search].blank? ? 'nodata' : params[:search]

    translated_query = translate_to_english(query)

    client = HTTPClient.new
    res = client.get("https://api.edamam.com/api/recipes/v2?type=public&q=#{CGI.escape(translated_query)}&app_id=#{ENV.fetch('application_id', nil)}&app_key=#{ENV.fetch('application_keys', nil)}")
    @foods = JSON.parse(res.body)
  end

  private

  def translate_to_english(query)
    api_key = ENV['DEEPL_KEY']
    uri = ("https://api-free.deepl.com/v2/translate")
    client = HTTPClient.new
    client.ssl_config.clear_cert_store
    client.ssl_config.set_trust_ca("/etc/ssl/certs")
    params = {
      auth_key: api_key,
      text: query,
      target_lang: "EN"
    }

    response = client.get(uri, query: params)
    parsed_response = JSON.parse(response.body)

    translation_text = parsed_response["translations"][0]["text"]
    translation_text
  end

end
app/views/edamams/index.html.erb
<div class="container">
  <div class="d-flex">
    <h3 class="text-center">海外のレシピ検索</h3>
    <div class="text-center"><%= render 'shared/how_to_edamams_api' %></div>
  </div>
  
  <%= form_with(url: edamams_path, method: :get, class: "search-form") do |f| %>
    <%= f.text_field :search, placeholder: "食材で検索してください", class: 'form-control' %>
    <%= f.submit '検索する', class: "btn-brown" %>
  <% end %>
</div>

<% if @foods.present? && @foods["hits"].present? %>
  <div class='m-3'>
    <% @foods["hits"].first(12).each_slice(3) do |recipes| %>
      <div class="row mb-3">
        <% recipes.each do |recipe| %>
        <div class='col-md-4'>
          <div class="card" style="background-color: #FFEEC1">
            <div class="card-body text-center">
              <h4 class="card-title" style='color: #6B493D; font-size: 16px;'><%= translate_to_japanese(recipe["recipe"]["label"]) %></h4>
              <%= image_tag recipe["recipe"]["image"], class: "card-img-bottom mx-auto", alt: "Card image", style: "width:70%; height: 70%; object-fit: contain;" %>
              <div class="text-center mt-3">
                <%= link_to '海外公式サイトへ', recipe["recipe"]["url"], class: "btn btn-warning", style: "color: #6B493D; font-size: 14px;" %>
              </div>
            </div>
          </div>
        </div>
      <% end %>
      </div>
    <% end %>
  </div>
<% end %>

今回の実装方針としては、
1.入力された値を日本語化してEdamamsAPIとして渡す
2.EdamamsAPIから取得したjsonから英語を日本語に翻訳する

上記の2点がポイントになります。

【ポイント1】


app/controllers/edamams_controller.rb
require 'httpclient'
require 'deepl'

# 上記の記述でDeepL及びAPIを実行できるようにする。それぞれrequire対象の詳細についてはgithub参照。

def translate_to_english(query)
    api_key = ENV['DEEPL_KEY']
    uri = ("https://api-free.deepl.com/v2/translate")
    client = HTTPClient.new
    # 上記から、環境変数などのセットを行う。(有料プランの場合、uriが上記ではなくなります。)
    
    client.ssl_config.clear_cert_store
    client.ssl_config.set_trust_ca("/etc/ssl/certs")
    # SSLなど証明書の情報をここで設定しておく。
    
    params = {
      auth_key: api_key,
      text: query,
      target_lang: "EN"
    }
    # 取得した日本語を英語に変換するので"EN"

    response = client.get(uri, query: params)
    parsed_response = JSON.parse(response.body)

    translation_text = parsed_response["translations"][0]["text"]
    translation_text
    # json.parse後の中身に関して後述。
  end

実際に、どのような挙動をしているのか確認しましょう。

app/controllers/edamams_controller.rb
def translate_to_english(query)
# 割愛
    translation_text = parsed_response["translations"][0]["text"]
    translation_text
    
    Rails.logger.info(parsed_response["translations"])
    # JSONの中身を検証。確認後に上記を削除します。

  end
log/development.log
  Parameters: {"search"=>"バナナ", "commit"=>"検索する"} # 検索値として、【バナナ】を確認
[{"detected_source_language"=>"JA", "text"=>"banana"}]# 一部抜粋。json形式内のtextがbananaに翻訳されたことを確認

以上、コントローラから日本語から英語に変換する作業を紹介しました。
今度は英語から日本語に変換する作業を紹介します。

【ポイント2】


今回は、viewの表示をhelper配下にmoduleで日本語表記になるように、設定したいと思います。

まずは、呼び出し元を下記のようにします。

app/views/edamams/index.html.erb
<% @foods["hits"].first(12).each_slice(3) do |recipes| %>
      <div class="row mb-3">
        <% recipes.each do |recipe| %>
            
            <h4 class="card-title" style='color: #6B493D; font-size: 16px;'><%= translate_to_japanese(recipe["recipe"]["label"]) %></h4> #ここで、moduleから呼び出せるように命名する。

(edamamsAPIの引数の詳細については本筋と逸れるので割愛します。確認したい場合、edamamsAPI取得後に、local環境を用意し、postmanなどで検証してください。)

app/helpers/translations_helper.rb
module TranslationsHelper
    def translate_to_japanese(query)
      api_key = ENV['DEEPL_KEY']
      uri = "https://api-free.deepl.com/v2/translate"
      client = HTTPClient.new
      # 上記で環境変数の設定
      
      client.ssl_config.clear_cert_store
      client.ssl_config.set_trust_ca("/etc/ssl/certs")
      # SSLの設定
      
      params = {
        auth_key: api_key,
        text: query,
        target_lang: "JA"
      }
      # 英語から日本語に変換したいので、JAに設定。
  
      response = client.get(uri, query: params)
      parsed_response = JSON.parse(response.body)
  
      translation_japanese = parsed_response["translations"][0]["text"]
      translation_japanese
    end
  end

先ほどとの相違点としては、view側で表示したいので
1.helperに設定したこと
2.target_lang: "JA"で日本語翻訳するように設定したこと

上記の2点になります。

ここまでで、今回の実装要件を満たすことができました!
完成系が下記になります。

レシピ検索機能

【引用】


18
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?