Skip to content

Override für Direktnachrichten-E-Mail-Benachrichtigungen #620

Description

@larsUE

Problem

Wir haben in Decidim ein ärgerliches/nicht zu Ende gedachtes Feature (Bug?) gefunden, welches verhindert, dass wiederholte PMs E-Mail-Benachrichtigungen auslösen. Ausführliche Beschreibung hier: decidim/decidim#17197

In Kürze: Decidim sendet E-Mail-Benachrichtigungen bei Direktnachrichten nur, wenn der Empfänger genau eine ungelesene Nachricht in der Konversation hat (unread_count == 1).

Folgt eine zweite Nachricht, ohne dass der Empfänger die Konversation geöffnet hat, wird keine weitere E-Mail verschickt — auch nicht nach längerer Zeit.

Ziel

Zürich-spezifischer Override: E-Mail-Benachrichtigungen sollen nach einer konfigurierbaren Wartezeit (z. B. 1 Stunde) erneut verschickt werden, wenn neue ungelesene Nachrichten eintreffen.


Logik

Statt nur bei unread_count == 1 zu benachrichtigen, gilt:

  1. Erste ungelesene Nachricht → E-Mail senden (wie bisher)
  2. Mehrere ungelesene Nachrichten → E-Mail senden, wenn die vorherige ungelesene Nachricht (die zweitneueste) älter als die Wartezeit ist (z. B. 1 Stunde)
Szenario Ergebnis
A → B → B (innerhalb 1 Stunde) Eine E-Mail (Spam-Schutz bleibt)
A → B → (1+ Stunde) → B Zweite E-Mail wird gesendet
A → B → (1+ Stunde) → B → B (innerhalb 1 Stunde) Eine Folge-E-Mail, kein E-Mail-Burst

Hinweis: Die Wartezeit bezieht sich auf den Abstand zwischen Nachrichten, nicht auf die Zeit seit der letzten E-Mail. Dafür werden die vorhandenen created_at-Zeitstempel der Receipts genutzt — keine DB-Migration nötig.


Technischer Ansatz

Override per prepend auf Decidim::Messaging::ReplyToConversation, analog zu bestehenden Zürich-Overrides (PushNotificationMessage, LayoutHelper, …).

  • Betroffen: Nur Antworten in bestehenden Konversationen (ReplyToConversation)
  • Unverändert: Neue Konversationen (StartConversation), Push-/In-App-Benachrichtigungen

Code-Skizze

app/commands/decidim_zuerich/messaging/reply_to_conversation.rb

module DecidimZuerich
  module Messaging
    module ReplyToConversation
      NOTIFICATION_RETRY_AFTER = 1.hour

      private

      def notify(recipient)
        return unless should_send_email_notification?(recipient)
        return unless recipient.accepts_conversation?(form.context.current_user)

        yield unless @already_notified.include?(recipient)
        @already_notified.push(recipient)
      end

      def should_send_email_notification?(recipient)
        unread = conversation.receipts.unread_by(recipient)
        return true if unread.count == 1

        previous_unread = unread.order(created_at: :desc).offset(1).first
        return false unless previous_unread

        previous_unread.created_at < NOTIFICATION_RETRY_AFTER.ago
      end
    end
  end
end

Registrierung in config/initializers/decidim_zuerich_customization.rb

[Decidim::Messaging::ReplyToConversation, DecidimZuerich::Messaging::ReplyToConversation]

in der PREPENDS-Liste.


Varia

  • Tracken, wie sich der Zustand des Issues bei Decidim verhält.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Ready

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions