Discourse Translator

:discourse2: Summary Discourse Translator translates posts on Discourse using Microsoft, Google, or Yandex translation APIs.
:hammer_and_wrench: Repository Link https://github.com/discourse/discourse-translator
:open_book: Install Guide How to install plugins in Discourse

Features

  • Each post is only translated once per locale which saves you :moneybag:
    • Note that language detection is also run once for every post. Be careful when enabling this on old and large forums.
  • Access Token is cached server side for faster translations.
  • Translations are rate limited to 3 per minute by default (admins can configure this value)

Translation Services Supported

Configuration Steps

Microsoft
  1. Follow the steps in Microsoft Translator API on Azure to obtain a subscription key. You may pick from any of the available subscription offers.

  2. In your Discourse, under Admin > Settings > Plugins, enter the subscription key that you’ve obtained from the steps above.

enter subscription key

  1. In your Discourse, under Admin > Settings > Basic Setup, enable allow user locale.
Google Translator
  1. Go to https://console.developers.google.com

  2. Click on My Project

my project

  1. Click on the :heavy_plus_sign: to create a new project

  1. Enter your project name and click create

  2. Select Enable API and search for Google Cloud Translator API. Look for the enable button and click it to enable the API. Note that there is no free tier for the Google Translator API so it may prompt you to enable billing.

  3. Once you’re done, click on credentials in the left menu

credentials

  1. Click create credentials and select API key. Copy the API Key and paste it into the translator google api key site setting in Discourse.

  2. In Discourse, under Admin > Settings > Basic Setup, enable allow user locale.

Settings

Name Description
translator enabled Allow inline translation of posts.
translator The provider of the translation service.
translator azure subscription key Azure Subscription Key
translator azure region Azure Region
translator azure custom subdomain Required if using a Virtual Network or Firewall for Azure Cognitive Services. Note: Only enter the custom subdomain not the full custom endpoint.
translator aws region AWS Region
translator aws key id AWS Key ID
translator aws secret access AWS secret access key
translator aws iam role AWS IAM Role
translator google api key Google API Key
translator yandex api key Yandex API Key
translator libretranslate endpoint LibreTranslate Endpoint
translator libretranslate api key LibreTranslate API Key
max translations per minute The number of translations per minute a regular user can perform.
restrict translation by group Only allowlisted groups can translate
restrict translation by poster group Only allow translation of posts made by allowlisted users

Known Issues

  • Does not translate text within polls generated by discourse-poll plugin.
  • Images are enlarged upon translating.

:discourse2: Hosted by us? This plugin is available on our Enterprise plan.

Last edited by @JammyDodger 2024-06-18T14:19:34Z

Check documentPerform check on document:
「いいね!」 102

投稿が新しいトピックに分割されました:フォーラムのトップ投稿を翻訳するためにLLMを使用するソリューションを探しています

投稿が新しいトピックに分割されました:言語検出サービス用の個別の設定オプションを追加する

投稿が新しいトピックに分割されました: Discourseによってホストされているフォーラムは、LibreTranslateのローカルインスタンスを使用していますか?

過去には正常に動作していたセルフホスト型のLibreTranslateを使用していますが、現在、「Job exception: The translator service is currently not available.」というエラーが頻繁に発生しています。URLは過去に動作していたもので、アクセスするとLibreTranslateのWebページが表示されます。LibreTranslateインスタンスはプライベートでインターネットからのアクセスがないため、API/トークンは必要ありません。

バックトレースは以下の通りです。

Message (548 copies reported)

Job exception: The translator service is currently not available.

Backtrace

/var/www/discourse/plugins/discourse-translator/services/discourse_translator/libretranslate.rb:168:in `result'
/var/www/discourse/plugins/discourse-translator/services/discourse_translator/libretranslate.rb:85:in `detect'
/var/www/discourse/plugins/discourse-translator/plugin.rb:120:in `block in execute'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/plugins/discourse-translator/plugin.rb:119:in `execute'
/var/www/discourse/app/jobs/base.rb:305:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.0.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.0.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:292:in `block in perform'
/var/www/discourse/app/jobs/base.rb:288:in `each'
/var/www/discourse/app/jobs/base.rb:288:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:202:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:170:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:177:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:132:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:179:in `block in invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:182:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:169:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:113:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq.rb:44:in `block in <module:Sidekiq>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:263:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:13:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:80:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:124:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:39:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:123:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:168:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:78:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:68:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:8:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:17:in `block in safe_thread'

これを解決するにはどうすればよいでしょうか?

「いいね!」 2

「Discourse」にはまだ「ヒンディー語」のロケールオプションはありません。しかし、「ヒンディー語」の翻訳はさまざまなサービスで利用可能です(私は「Microsoft Azure」を使用しています)。

では、Discourseのインターフェースが英語のままでも、すべての投稿/任意の投稿を「ヒンディー語」に翻訳するように設定するにはどうすればよいでしょうか?これは可能なのでしょうか?

「いいね!」 1

この質問をディスコースフォーラムにもクロス投稿しています。

「いいね!」 3

フォーラムにこの翻訳者を追加することを検討していましたが、主に2つの懸念があります。

1. 翻訳を変更することは可能ですか?
特定の用語が特定の翻訳になるようにしたいと考えています。そのため、利用可能な翻訳を確認し、必要に応じて変更を加える機能が必要です。

2. いつ投稿は「再翻訳」されますか?
フォーラムの投稿は頻繁に編集されます。すべてのタイポ修正が法外な翻訳費用につながることを防ぐにはどうすればよいですか?また、新しい変更が翻訳に正確に反映されることをどのように保証できますか?

「いいね!」 3

これは不可能だと思われます。ベンダー(Microsoft/Google)のレベルで変更する必要があるためです。翻訳されたコンテンツが単語置換機能の対象となる場合を除き、それを使用できます。

ただし、以下のような機能リクエストがあります。

  1. 最初の投稿が異なる言語で書かれている場合に、英語に自動翻訳する。
  2. スレッド全体を一度に翻訳するボタンを設ける。
  3. ユーザーレベルでフォーラム全体に自動翻訳機能を有効にする。つまり、ユーザーがプロフィールでルーマニア語のみを話すと選択した場合、すべてのコンテンツがルーマニア語に翻訳されます。複数の言語を話すと選択した場合、投稿はその言語以外の場合にのみ翻訳されます。
「いいね!」 2

サイト管理者として、これを読んで驚きました。

この隠し設定はどこにありますか? :smiling_face_with_sunglasses:

「いいね!」 1
./launcher enter app
rails c
SiteSetting.automatic_translation_backfill_rate = <wanted value>
exit
exit

しかし、より新しいバージョンではもう存在しないと思います。

「いいね!」 2

これらはどのように学習するのですか? :sweat_smile: わかりました、ありがとうございます! 念のため、チームからの回答をお待ちしています。

「いいね!」 1

2つの方法があります:検索と ask.discourse.com を利用することです。

「いいね!」 3
「いいね!」 3

翻訳されたトピックの通知が通知バーに表示されないようです。

「いいね!」 1

また、私の投稿がリンクを介して間違った言語に翻訳されてしまいました。


コンポーザーで確認したところ、実際に書いたのは次のとおりです。

翻訳した際に、ワンボクシングも機能しなかったことに気づきました。

「いいね!」 1

スクリーンショットの通知は、投稿トピックの元のタイトルを使用しているため、現時点では「正しい」です。将来的には、通知(トピックタイトル)が翻訳されるようにします。

上記の投稿については、機械翻訳が誤作動し、「スペイン語(es)」として誤検出され、その後の翻訳も不正確でした。これは修正されました。より良い翻訳プロンプトで反復処理を行っています。

「いいね!」 2

Discourse-translator プラグインをインストールした際に、このエラーが発生しました。私の Discourse のバージョンは 3.5.0.beta1 です。

I, [2025-04-24T01:33:20.510994 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'bundle exec rake db:migrate'
        82: from /usr/local/bin/bundle:25:in `<main>'
        81: from /usr/local/bin/bundle:25:in `load'
        80: from /usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/exe/bundle:20:in `<top (required)>'
     ....
        10: from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/lazy_load_hooks.rb:87:in `with_execution_control'
        9: from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/lazy_load_hooks.rb:94:in `block in execute_hook'
        8: from /var/www/discourse/config/application.rb:249:in `block in <class:Application>'
        7: from /var/www/discourse/lib/plugin.rb:6:in `initialization_guard'
        6: from /var/www/discourse/config/application.rb:249:in `block (2 levels) in <class:Application>'
        5: from /var/www/discourse/config/application.rb:249:in `each'
        4: from /var/www/discourse/lib/plugin/instance.rb:629:in `notify_after_initialize'
        3: from /var/www/discourse/lib/plugin/instance.rb:629:in `each'
        2: from /var/www/discourse/lib/plugin/instance.rb:631:in `block in notify_after_initialize'
        1: from /var/www/discourse/plugins/discourse-translator/plugin.rb:40:in `block in activate!'
/var/www/discourse/plugins/discourse-translator/lib/discourse_translator/inline_translation.rb:86:in `inject': protected method `register_topic_preloader_associations' called for an instance of Plugin::Instance (NoMethodError)

どうすれば修正できますか?

「いいね!」 1

こんにちは、エラーはプラグインをインストールする前にDiscourseを最初に更新することで軽減できます。

register_topic_preloader_associations メソッドは、保護されたものから公開されたものに昇格しました。

「いいね!」 4

ありがとうございます。Discourse を最新版にアップグレードした後、正常にインストールできました。

「いいね!」 2