同じ返信に関する複数の通知を受け取る

初めて、編集でリンク、引用、またはメンションを追加していないにもかかわらず、同じ返信に対する2回目の通知に気づきました。これは、Topics from some categories do not appear on /latest - #36 by JammyDodger の編集後でした。このケースは、以下の再現手順とは少し異なりますが、根本的な問題は同じだと思います。

2回目の発生は、Messages section for sidebar - #13 by nathank で発生しました。同様に、編集で通知を発生させるようなものは何も追加されず、引用は以前から存在していたにもかかわらず、再度通知されました。

以下に、機能した再現手順を示します[1](少なくともほとんどの場合。場合によっては、編集で@メンションを追加しても新しい通知はトリガーされません)。

3人のユーザーが必要です:OP、notifiedUser、spammer

  1. OPがトピックを作成します
  2. notifiedUserが返信します
  3. OPがnotified userの投稿に返信します
    notifiedUserが返信について通知されます(期待通り)
  4. spammerがnotifiedUserの投稿に返信します。返信には、notifiedUserによる別の投稿へのリンクと、返信元の投稿からの引用が含まれます。(オプション:notifiedUserを@メンションすることもできます)
    notifiedUserが返信について通知されます(期待通り)
    [もし@メンションを追加した場合、通知は@メンションに関するものです(期待通り)]
  5. notifiedUserが新しい返信を読んで通知を既読にし、見逃さないようにどこか別の場所に移動します。
  6. spammerが返信を編集してタイポを修正します(またはedit1を追加します)
    notifiedUserが引用されたことについて通知されます(予期せず。彼らはすでにこの返信について通知されており、引用は以前から存在していたため、伝える必要はありません)
  7. spammerが別のタイポを修正するために返信を再度編集します(またはedit2を追加します)
    notifiedUserがリンクされたことについて通知されます(予期せず。彼らはすでにこの返信について通知されており、リンクは以前から存在していたため、伝える必要はありません)

ビデオは最終ステップの5〜7のみを示しています。spammerが左側、notifiedUserが右側です。


  1. 少なくともほとんどの場合。場合によっては、編集で@メンションを追加しても新しい通知はトリガーされません。 ↩︎

「いいね!」 3

post_alerter.rb

589-599行目を以下のように変更します。
 # linked, quoted, mentioned, chat_quoted は、すでに返信通知がある場合は抑制される可能性があります
 if [
      Notification.types[:quoted],
      Notification.types[:linked],
      Notification.types[:mentioned],
      Notification.types[:chat_quoted],
    ].include?(type)
   if existing_notifications.find { |n| n.notification_type == Notification.types[:replied] }
     return
   end
 end

 以下のように:
 # linked, quoted, mentioned, chat_quoted は、この投稿に関する既存の通知がある場合は抑制される可能性があります
 if [
      Notification.types[:quoted],
      Notification.types[:linked],
      Notification.types[:mentioned],
      Notification.types[:chat_quoted],
    ].include?(type)
   return if existing_notifications.any?
 end

これで機能しますが、他の通知(例えば、抑制したい可能性のあるプラグイン通知など)がここをすり抜ける可能性があるため、少し懸念があります。

@lindsey ここで通知を抑制すべきなのはいつか、製品に関する質問があります。

この小さな修正は一歩前進でしょうか?

どうでしょうか。それは私の動画の返信通知ではないでしょうか?それなのに、引用に関する通知と、その後のリンクに関する通知がまだあります。したがって、他の通知タイプにそれを拡張しても、ここでは役立たないかもしれません。しかし、他のエッジケースをカバーしている可能性はあります。
私の再現手順での問題は、「2件の返信」通知ではないかと思います。返信が編集されたときに、その返信による既存の通知のチェックを妨げるのでしょうか?

一般的に、私が以前に読んだときにすべてのトリガーがその投稿内に存在していた場合、編集によって追加の通知が発生することはないと予想します。メンション/リンク/引用とは無関係なタイポを修正しても、新しい通知が発生するはずではありません。
トリガーが置き換えられた場合、2番目の通知を受け取るよりも、既存の未読通知が変更される(または置き換えられる)方が良いと思います。ノイズを避けるためにユーザーの投稿から@メンションを削除しても、引用に関する2番目の通知が発生するはずではありません。@メンションに関する通知は消えるはずだと予想します
新しい通知を望むのは、編集によってより重要な通知タイプが追加された場合だけだと思います。誰かが私の投稿にリンクし、その後で私に直接話しかけているように見える編集で私に@メンションした場合、それを知らせるのは理にかなっています。編集によってトピックがバンプされなくなったため、@メンションはユーザーに編集について警告するのに役立つ方法かもしれません

Moin がユーザー視点での理想を説明していると思いますが、この部分を正しく実装するのは難しいと思います。

アプリ内通知については、これで対応できるかもしれませんが、プッシュ通知やメール通知は送信後に取り消すことはできません。(一般的に、通知に関する複雑さを増やすことには消極的なので、アプリ内とメール/プッシュで通知が異なることを許容する人もいるかもしれませんが、私はこれは見送る方が良いと思います。)

ただし、これには同意します。

  • 投稿がユーザーに通知すべき場合(例:投稿者がユーザーAを引用した場合)、関連するユーザーに通知します(例:ユーザーAは引用されたという通知を受け取ります)。
  • その投稿の編集が、誰に通知すべきか、またはなぜ通知すべきかを変更しない場合(例:投稿者がタイポを編集した場合)、誰も通知しません。
  • その投稿の編集が、誰に通知すべきか(例:投稿者がユーザーBに言及した場合)またはなぜ通知すべきか(例:投稿者がユーザーAに言及した場合)を変更する場合、影響を受けるユーザーに通知します(例:ユーザーBはメンション通知を受け取り、ユーザーAはメンション通知を受け取ります)。

@moin、これでよろしいでしょうか?

「いいね!」 1

はい、ここでプルリクエストをクローズし、これを機能として扱います。

特に、ここにギャップがあります。

  • @Moin は…古い通知の更新を希望しています
  • @lindsey は、投稿に編集された新しい情報に対する…新しい通知を希望しています

ここで完全に連携するには、かなり複雑な追跡が必要になります…変更の規模を評価していますが、正直なところ、現時点では何もしないのがおそらく最も簡単です。なぜなら、その変更は非常に壊れやすいものになるからです。

どのメンションが新しいものか古いものかを抽出するには、パーサー(現時点では解析していません)または壊れやすい正規表現のいずれかが必要になります。

これを機能 @Moin に移行し、現時点では私のプルリクエストをクローズします。

何よりも、投稿に変更がない場合に通知が届くのはごめんです。私がすでに同じトピックについて2つの通知が折りたたまれたという理由だけで通知されていた場合、タイポを修正しただけで通知されるべきではありません。そして、12月にそれが起こるまで、何年もそれに気づきませんでした。

コードに基づいて再現手順を見つけようとしたときに、この問題についてAIが私に伝えたことの要約をChatGPTに作成してもらいました。

要約: 二重通知が通常防止される理由と、ここで失敗する理由 AI

中核的な問題

二重防止は、編集された投稿にまだスコープが設定されている返信通知を見つけることに依存していますが、返信通知は折りたたまれたり、破棄されたり、別の投稿に再アタッチされたりします。
その結果、編集時の抑制は、ユーザーがすでにその返信について通知されていることを確実に検出できません。


PostAlerterでは、二重通知は次のように防止されます。

  1. 投稿作成時にすでに通知されたユーザーを追跡する
notified = []
  1. 返信通知が存在する場合、二次トリガーを抑制する
if [:quoted, :linked, :mentioned, :chat_quoted].include?(type)
  return if existing_notifications.find { |n|
    n.notification_type == Notification.types[:replied]
  }
end

これは、同じ投稿についてユーザーに二重に通知するのを避けるためのものです。

  1. 返信通知の折りたたみ
    返信通知 (:replied) はトピックごとに折りたたまれます。
destroy_notifications(user, COLLAPSED_NOTIFICATION_TYPES, topic)

残った通知は次のように再アタッチされます。

post = first_unread_post(user, topic)

そのため、通知は元のトリガーとなった投稿を表さなくなります。その結果、post_numberの一致に依存する抑制ロジックは、編集された投稿に対する以前の通知を確実に検出できません。


再現ケースで失敗する理由

再現ケースでは:

  • ユーザーは最初に返信について通知されます
  • 複数の返信が存在する場合、返信通知は折りたたまれます
  • 折りたたまれた通知は:
    • 編集された投稿にもはや存在しないか、
    • 異なる post_number で存在します
  • 編集時:
    • 返信ロジックは実行されません (new_record == false)
    • 抑制チェックは投稿スコープの :replied 通知のみをチェックします
    • 何も見つからない → 抑制は失敗します
  • 再度引用/リンク検出が実行され、新しい通知が作成されます

ユーザーの視点から:

「この返信についてはすでに通知されています。」

コードの視点から:

「この投稿に対する既存の通知はありません。」

どちらも真実です。

公開カテゴリでテストユーザーに言及するトピックを作成し、数分後に非公開カテゴリに移動すると、メールで@mentionの通知を受け取っていたにもかかわらず、インターフェースからも通知が削除されます。
したがって、メールが送信されたにもかかわらず削除されるアプリ内通知は、すでに存在しています。

mcwumbly が彼の トピック にタグを追加したときに、私の投稿がリンクされたという新しい通知を受け取るのは、まだバグのように感じます。彼がトピックを投稿したときにはすでにリンクは存在しており、引用については通知を受けています。タグが追加されたこと以外、何も変わっていません。それなのに、なぜ編集が2回目の通知をトリガーすることが期待されているのでしょうか?

最初の投稿の手順に加えて、次の手順でも発生します。

  1. notifiedUser がトピックを作成する
  2. スパマーがリンクされたトピックとして返信する。投稿にはデフォルトでリンクが含まれているため、@メンションと引用を追加するだけで済みます
    → notifiedUser は @メンションについて通知を受け取り(期待通り)、トピックを読みます
  3. スパマーがトピックにタグを追加する
    → notifiedUser は投稿で引用されたことについて通知を受け取ります(予期せず、すでに通知を受けており、何も変わっていません)
  4. スパマーがトピックのタイトルを編集する
    → notifiedUser は投稿でリンクされたことについて通知を受け取ります(予期せず、以前に通知を受けており、投稿はまだ変更されていません)

「いいね!」 2