Tradutor de Discourse

: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 curtidas

Uma postagem foi dividida em um novo tópico: Estou procurando uma solução para usar um LLM para traduzir as postagens principais do meu fórum

Uma postagem foi dividida em um novo tópico: Adicionando uma opção para uma configuração separada para o serviço de detecção de idioma

Uma postagem foi dividida em um novo tópico: Os fóruns hospedados pelo Discourse usam uma instância local do LibreTranslate?

Estou usando o LibreTranslate auto-hospedado, que funcionou bem no passado, mas agora estou recebendo muitos erros repetidos de "Exceção de trabalho: O serviço de tradução não está disponível no momento". Verifiquei o URL, que tem funcionado bem no passado. Se eu acessar o URL, a página web do LibreTranslate é exibida. Não é necessária API/token porque minha instância do LibreTranslate é privada e não tem acesso à Internet.

O backtrace mostra:

Mensagem (548 cópias relatadas)

Exceção de trabalho: O serviço de tradução não está disponível no momento.

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'

Alguma ideia de como posso consertar isso?

2 curtidas

A opção de localidade ‘Hindi’ ainda não está disponível no ‘Discourse’. Mas a tradução para ‘Hindi’ está disponível por meio de diferentes serviços (estou usando o ‘Microsoft Azure’).

Então, como podemos configurar para traduzir todas/quaisquer postagens não em Hindi para ‘Hindi’, mesmo quando a interface do Discourse continuar em inglês? Isso é possível?

1 curtida

Tentando postar esta pergunta em seu fórum de discussão também.

3 curtidas

Estava pensando em adicionar este tradutor ao nosso fórum. No entanto, tenho duas preocupações principais:

1. É possível alterar as traduções?
Quero garantir que certos termos sejam traduzidos de uma maneira específica. Para isso, preciso ter a capacidade de visualizar as traduções disponíveis e fazer alterações, se necessário.

2. Quando uma postagem será ‘traduzida novamente’?
Algumas postagens do fórum são editadas com bastante frequência. Como posso garantir que cada erro de digitação corrigido não resulte em custos de tradução exorbitantes? Além disso, como posso garantir que as novas alterações sejam atualizadas com precisão nas traduções?

3 curtidas

Acredito que isso não seja possível, pois você teria que modificar no nível do fornecedor (Microsoft/Google). A menos que o conteúdo traduzido esteja sujeito ao recurso de substituição de palavras, então você pode usá-lo.

Aqui está uma solicitação de recurso:

  1. Traduzir automaticamente a primeira postagem para o inglês caso esteja escrita em um idioma diferente.
  2. Ter um botão para traduzir todo o tópico de uma vez.
  3. Ter o recurso de tradução automática habilitado para todo o fórum em nível de usuário. Ou seja, se o usuário selecionar em seu perfil que fala apenas, por exemplo, romeno, então todo o conteúdo será traduzido para o romeno. Se ele selecionar que fala vários idiomas, as postagens só serão traduzidas se não estiverem nesses idiomas.
2 curtidas

Como administrador do site, fiquei surpreso ao ler isto:

Onde está essa configuração oculta? :smiling_face_with_sunglasses:

1 curtida
./launcher enter app
rails c
SiteSetting.automatic_translation_backfill_rate = <valor desejado>
exit
exit

Mas acho que isso não existe mais, em versões mais recentes de qualquer forma.

2 curtidas

Como você aprende essas coisas? :sweat_smile: Ok, obrigado! Vou aguardar uma resposta da equipe, para ter certeza.

1 curtida

Duas maneiras: usando a pesquisa e ask.discourse.com

3 curtidas
3 curtidas

Notificações do tópico intitulado que foi traduzido não parecem ser traduzidas na barra de notificações:

1 curtida

Além disso, minha postagem foi traduzida para o idioma incorreto em um link?


Olhando no editor, foi o que eu realmente escrevi:

Notei que o oneboxing também não funcionou quando traduzi.

1 curtida

A notificação na sua captura de tela usa o título original do tópico da sua postagem, então ela está “correta” por enquanto. Garantiremos que as notificações (títulos de tópicos) sejam traduzidas no futuro.

Quanto à postagem acima, nossa tradução automática estava com problemas e foi incorretamente detectada como “espanhol (es)”, além de ter uma tradução ruim subsequente. Isso foi corrigido. Estamos iterando com melhores prompts para traduções.

2 curtidas

Tive este erro ao instalar o plugin discourse-translator. Minha versão do 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)

Como posso consertar isso?

1 curtida

Olá, o erro pode ser mitigado atualizando o Discourse primeiro antes de instalar o plugin.

O método register_topic_preloader_associations foi promovido de protegido para público.

4 curtidas

Obrigado, instalei com sucesso após atualizar o Discourse para a versão mais recente.

2 curtidas