收到关于同一回复的多条通知

我第一次注意到在编辑后收到了关于同一回复的第二个通知,而编辑中没有添加链接、引用或提及,是在编辑 Topics from some categories do not appear on /latest - #36 by JammyDodger 之后。这种情况与我下面的重现步骤略有不同,但我认为根本问题是相同的。

发生这种情况的第二个帖子是在 Messages section for sidebar - #13 by nathank

以下是我找到的有效(至少大多数时候有效,有时即使在编辑中添加 @提及也不会触发新通知)的重现步骤:

你需要 3 个用户:OP(楼主)、notifiedUser(被通知用户)、spammer(垃圾信息发送者)

  1. OP 创建一个主题
  2. notifiedUser 回复
  3. OP 回复 notifiedUser 的帖子
    notifiedUser 收到回复的通知(预期)
  4. spammer 回复 notifiedUser 的帖子。回复中包含一个指向 notifiedUser 的另一个帖子的链接和一个对你回复的帖子的引用。(可选:你也可以 @mention notifiedUser)
    notifiedUser 收到回复的通知(预期)
    [如果你添加了 @mention,通知是关于 @mention 的(预期)]
  5. notifiedUser 阅读新回复以将通知标记为已读,然后导航到别处,这样我们就不会错过通知。
  6. spammer 编辑回复并修复一个拼写错误(或添加 edit1)
    notifiedUser 收到被引用的通知(意外,他们之前已经收到了关于此回复的通知,并且引用之前就存在,无需再次告知)
  7. spammer 再次编辑回复以修复另一个拼写错误(或添加 edit2)
    notifiedUser 收到被链接的通知(意外,他们之前已经收到了关于此回复的通知,并且链接之前就存在,无需再次告知)

视频仅显示最后步骤 5-7。Spammer 在左边,notifiedUser 在右边

3 个赞

post_alerter.rb

将第 589-599 行从:
 # linked, quoted, mentioned, chat_quoted may be suppressed if you already have a reply notification
 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 may be suppressed if you already have any notification about this 
 post
 if [
      Notification.types[:quoted],
      Notification.types[:linked],
      Notification.types[:mentioned],
      Notification.types[:chat_quoted],
    ].include?(type)
   return if existing_notifications.any?
 end

这样做可行,但我确实有点担心,因为可能会遗漏其他通知。(例如插件通知,我们可能希望抑制这些通知)

@lindsey 这里有一个关于产品的问题,我们应该在什么时候抑制通知?

我想这个小修复算是一个进步?

我不确定。那不是我视频中的回复通知吗?然而,仍然有一个关于引用和链接的通知。因此,将此扩展到其他通知类型可能在这里没有帮助。但这可能涵盖了其他边缘情况。
我想知道我的复现中的问题是否是“2 条回复”通知。当回复被编辑时,这会破坏对该回复现有通知的检查吗?

总的来说,如果所有触发条件在我阅读帖子之前就已经存在,我希望编辑不会产生额外的通知。修复一个与提及/链接/引用无关的拼写错误不应该导致新的通知。
我认为,如果一个触发器被替换,我更希望现有的未读通知被更改(或替换),而不是收到第二个通知。删除用户帖子中的 @提及以避免噪音不应该导致关于引用的第二个通知。我希望关于 @提及的通知消失
我认为我希望收到新通知的唯一情况是编辑添加了更重要的通知类型。因此,当有人链接了我的帖子,然后稍后进行编辑并 @提及我时,通知我是有意义的,因为他们似乎不再谈论我写的内容,而是直接对我说话。由于编辑不再顶起主题,@提及可能是一种提醒用户注意编辑的有用方式

我认为 Moin 从用户角度描述了理想情况,但我认为我们很难把这部分做好:

也许我们可以为应用内通知做到这一点,但我们无法撤销推送通知或电子邮件通知的发送。(一般来说,我倾向于不对通知增加更多复杂性,所以虽然有些人可能可以接受应用内通知和电子邮件/推送通知不同,但我更希望我们放弃这一点。)

不过,我同意这个观点:

  • 如果帖子应该通知用户(例如,帖子作者引用了用户 A),则通知相关用户(例如,用户 A 收到被引用的通知)。
  • 如果对该帖子的编辑没有改变应该通知谁或为什么通知(例如,帖子作者编辑了一个拼写错误),则不通知任何人。
  • 如果对该帖子的编辑确实改变了应该通知谁(例如,帖子作者提到了用户 B)或为什么通知(例如,帖子作者提到了用户 A),则通知受影响的用户(例如,用户 B 收到提及通知,用户 A 收到提及通知)。

@moin 你觉得这样对吗?

1 个赞

我将在此处关闭我的拉取请求(PR),并将其称为一个功能。

这里有一个特别的空白:

  • @Moin 希望…更新旧的通知
  • @lindsey 希望…针对编辑到帖子中的新信息发送新的通知

要完全对齐这一点需要非常复杂的跟踪……我正在评估更改的规模,但说实话,目前什么都不做可能是最简单的,因为更改最终会非常脆弱。

提取哪些提及是新的,哪些是旧的,这需要一个解析器(我们目前不解析)或脆弱的正则表达式。

将此移至功能 @Moin,暂时关闭我的 PR。

最重要的是,如果帖子中没有任何变化导致需要发送通知,我不想再收到通知。更正一个拼写错误不应该通知我,如果我因为同一个主题的 2 条通知之前被折叠了而已经被通知过的话。而且我直到去年 12 月发生这种情况之前,从未注意到这一点。

当我试图根据代码查找重现步骤时,我让 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 通知
    • 未找到任何通知 → 抑制失败
  • 引用/链接检测再次运行并创建新的通知

从用户的角度来看:

“我已经收到了关于这个回复的通知。”

从代码的角度来看:

“这个帖子没有现有的通知。”

两者都是正确的。

当我创建一个提及我的测试用户(testuser)在公开分类中的主题,并在几分钟后将其移动到私密分类时,该通知也会从界面中移除——尽管他们收到了关于@提及的电子邮件。
因此,即使发送了电子邮件,但被删除的应用内通知已经存在了。