概要
コンテンツローカライズとAI翻訳を有効にすると、新しい投稿のプッシュ通知は、受信者が別の言語で閲覧しており、翻訳が数秒後に保存される場合であっても、ほぼ常に著者の原文を保持します。プッシュは投稿作成時にキューイングされ、翻訳ジョブが完了する前に一度だけ翻訳を検索します。
翻訳されたメールは本日、この返信(#44240)で発表されました。メールはこのタイミングの問題に晒されませんが、プッシュ通知は晒されるため、その変更がデプロイされると、同じ投稿のメールとプッシュ通知が同じメンバーに異なる言語で届くことになります。
メンバーが見るもの
インターフェース言語が英語のメンバーが、フランス語で書かれた新しいトピックのプッシュ通知を、ブラウザおよびモバイルで受信します。通知の本文はフランス語です。通知を開くと、投稿は英語で表示されます。
測定
release/2026.7(2026.7.3)のサイト、バンドルされた discourse-ai プラグイン、サポートされるロケール en、fr、de、it、翻訳は gemini-3.8-flash、言語検出は gemini-3.5-flash-lite を使用。
11件の翻訳済み投稿について、最初の翻訳は投稿作成後2〜3秒で保存され、3件中最後のものは4〜7秒後に保存されました。観察されたケースでは、受信者の言語への翻訳は投稿後2秒で保存されましたが、プッシュ通知はすでに原文とともに送信されていました。
この遅延は、以下のSQLで任意のサイトで確認できます:
SELECT p.id,
p.locale AS post_locale,
pl.locale AS translation_locale,
ROUND(EXTRACT(EPOCH FROM (pl.created_at - p.created_at))) AS seconds_after_post
FROM posts p
JOIN post_localizations pl ON pl.post_id = p.id
WHERE p.created_at > NOW() - INTERVAL '2 days'
ORDER BY p.id, pl.created_at
原因
:post_createdイベントで、discourse-ai はJobs::DetectTranslatePostをキューイングします(plugins/discourse-ai/lib/translation/entry_point.rb)。このジョブは1回のモデル呼び出しで言語を検出し、その後、サポートされている他の各ロケールへ順番に翻訳します。PostJobsEnqueuerは同じタイミングで:post_alertをキューイングします。PostAlerter.push_notificationは即座にJobs::DeliverPushNotificationをキューイングします。これは、受信者がpush_notification_time_window_mins(デフォルト1分)以内に確認した場合にのみ遅延し、その場合でもそのウィンドウの残り時間分だけです。DeliverPushNotification#localize_content!は、ジョブ実行時にuser.effective_localeに対してTopicLocalizationとPostLocalizationを一度だけ検索します。見つからない場合、元のタイトルと抜粋を送信します。待機や再試行は行われません。- 通知メールは
NotificationEmailerを通じ、email_time_window_mins(デフォルト10分)の遅延があるため、メールが構築される時点で翻訳が存在します。
app/jobs/regular/deliver_push_notification.rb は、v2026.7.3 と main の b5548f76(2026-10-05)で同一です。
要望
- 新しい投稿のプッシュ通知を、その翻訳が保存されるまで保留する。 1つの選択肢として:コンテンツローカライズが有効で、かつ投稿にまだ検出されたロケールがない場合、または受信者のロケールへのローカライズが存在しないが期待されている場合、短い遅延後に
DeliverPushNotificationを一度だけ再キューイングし、その後利用可能なものを送信する。数秒の遅延で、上記で測定されたケースをカバーできます。 - 共有ルールでコンテンツを選択する。 プッシュジョブは
effective_localeによる独自の検索を行っています。#44240 のメール変更はContentLocalization.show_translated_post?を通じ、post_versionを比較します。プッシュにも同じパスを使用することで、automatically_translateとunderstood_languagesを尊重し、古い翻訳をスキップし、メールおよびトピックビューと整合性を保つことができます。 - ライブアラートにも同じことを適用する。
PostAlerter.create_notification_alertで/notification-alert/:user_idに公開されるペイロードには、元のタイトルと抜粋が含まれています。モディファイアpost_alerter_live_notification_payloadは存在しますが、コアではペイロードがローカライズされていません。