From 97416ffdc1aa3f622e4a3f283bbcda67eab5d37e Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Mon, 23 Feb 2026 09:13:57 +0100 Subject: [PATCH] feat: email notification when receiving private message with opt-out toggle - New column: users.notify_email_messages (default true) - Send email via MS Graph when someone receives a private message - Toggle in /konto/prywatnosc to enable/disable email notifications - Email includes message preview, sender name, and direct link Co-Authored-By: Claude Opus 4.6 --- blueprints/auth/routes.py | 3 +- blueprints/messages/routes.py | 31 +++++++++++++++++++ database.py | 3 ++ .../063_add_notify_email_messages.sql | 16 ++++++++++ templates/konto/prywatnosc.html | 15 +++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 database/migrations/063_add_notify_email_messages.sql diff --git a/blueprints/auth/routes.py b/blueprints/auth/routes.py index c66c963..ea4d253 100644 --- a/blueprints/auth/routes.py +++ b/blueprints/auth/routes.py @@ -777,10 +777,11 @@ def konto_prywatnosc(): user.contact_prefer_email = request.form.get('prefer_email') == 'on' user.contact_prefer_phone = request.form.get('prefer_phone') == 'on' user.contact_prefer_portal = request.form.get('prefer_portal') == 'on' + user.notify_email_messages = request.form.get('notify_email_messages') == 'on' db.commit() logger.info(f"Privacy settings updated for user: {user.email}") - flash('Ustawienia prywatnosci zostaly zapisane.', 'success') + flash('Ustawienia prywatności zostały zapisane.', 'success') return redirect(url_for('auth.konto_prywatnosc')) return render_template('konto/prywatnosc.html', diff --git a/blueprints/messages/routes.py b/blueprints/messages/routes.py index 28eb0c2..b6b7191 100644 --- a/blueprints/messages/routes.py +++ b/blueprints/messages/routes.py @@ -14,6 +14,7 @@ from . import bp from database import SessionLocal, User, Company, PrivateMessage, UserNotification, UserBlock, Classified from utils.helpers import sanitize_input from utils.decorators import member_required +from email_service import send_email # ============================================================ @@ -191,6 +192,36 @@ def messages_send(): db.add(notification) db.commit() + # Send email notification if recipient has it enabled + if recipient.notify_email_messages != False and recipient.email: + try: + message_url = url_for('.messages_view', message_id=message.id, _external=True) + settings_url = url_for('auth.konto_prywatnosc', _external=True) + subject_line = f'Nowa wiadomość od {sender_name} — Norda Biznes' + preview = (content[:200] + '...') if len(content) > 200 else content + email_html = f''' +

Masz nową wiadomość

+

{sender_name} wysłał(a) Ci wiadomość na portalu Norda Biznes.

+ {f'

Temat: {subject}

' if subject else ''} +
+

{preview}

+
+

Odczytaj wiadomość

+

Możesz wyłączyć powiadomienia e-mail w ustawieniach prywatności.

+ ''' + send_email( + to=[recipient.email], + subject=subject_line, + body_text=f'{sender_name} wysłał(a) Ci wiadomość na portalu Norda Biznes. Odczytaj: {message_url}', + body_html=email_html, + email_type='message_notification', + user_id=recipient.id, + recipient_name=recipient.name + ) + except Exception as e: + import logging + logging.getLogger(__name__).warning(f"Failed to send message email notification: {e}") + flash('Wiadomość wysłana.', 'success') return redirect(url_for('.messages_sent')) finally: diff --git a/database.py b/database.py index 122f026..d07353d 100644 --- a/database.py +++ b/database.py @@ -322,6 +322,9 @@ class User(Base, UserMixin): contact_prefer_portal = Column(Boolean, default=True) # User prefers portal messages contact_note = Column(Text, nullable=True) # Additional note (e.g. best hours) + # Email notification preferences + notify_email_messages = Column(Boolean, default=True) # Email when receiving private message + # Relationships conversations = relationship('AIChatConversation', back_populates='user', cascade='all, delete-orphan') forum_topics = relationship('ForumTopic', back_populates='author', cascade='all, delete-orphan', primaryjoin='User.id == ForumTopic.author_id') diff --git a/database/migrations/063_add_notify_email_messages.sql b/database/migrations/063_add_notify_email_messages.sql new file mode 100644 index 0000000..16ce8d7 --- /dev/null +++ b/database/migrations/063_add_notify_email_messages.sql @@ -0,0 +1,16 @@ +-- Migration 063: Add email notification preference for private messages +-- Default TRUE so existing users get notified (they can opt-out) + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'users' + AND column_name = 'notify_email_messages' + ) THEN + ALTER TABLE users ADD COLUMN notify_email_messages BOOLEAN DEFAULT TRUE; + RAISE NOTICE 'Added notify_email_messages column'; + ELSE + RAISE NOTICE 'notify_email_messages column already exists'; + END IF; +END $$; diff --git a/templates/konto/prywatnosc.html b/templates/konto/prywatnosc.html index 6fde2c4..30f7af4 100644 --- a/templates/konto/prywatnosc.html +++ b/templates/konto/prywatnosc.html @@ -354,6 +354,21 @@ +
+

Powiadomienia e-mail

+ +
+
+
Nowe wiadomości prywatne
+
Otrzymuj e-mail, gdy ktoś wyśle Ci wiadomość prywatną na portalu
+
+ +
+
+