diff --git a/app/services/post_alerter.rb b/app/services/post_alerter.rb index 56ed07fddd3..ab86e75915b 100644 --- a/app/services/post_alerter.rb +++ b/app/services/post_alerter.rb @@ -392,13 +392,20 @@ class PostAlerter notification_data[:group_name] = group.name end + if original_post.via_email && (incoming_email = original_post.incoming_email) + skip_send_email = contains_email_address?(incoming_email.to_addresses, user) || + contains_email_address?(incoming_email.cc_addresses, user) + else + skip_send_email = opts[:skip_send_email] + end + # Create the notification user.notifications.create(notification_type: type, topic_id: post.topic_id, post_number: post.post_number, post_action_id: opts[:post_action_id], data: notification_data.to_json, - skip_send_email: opts[:skip_send_email]) + skip_send_email: skip_send_email) if !existing_notification && NOTIFIABLE_TYPES.include?(type) && !user.suspended? # we may have an invalid post somehow, dont blow up @@ -422,6 +429,11 @@ class PostAlerter end + def contains_email_address?(addresses, user) + return false if addresses.blank? + addresses.split(";").include?(user.email) + end + def push_notification(user, payload) if SiteSetting.allow_user_api_key_scopes.split("|").include?("push") && SiteSetting.allowed_user_api_push_urls.present? clients = user.user_api_keys diff --git a/spec/fabricators/incoming_email_fabricator.rb b/spec/fabricators/incoming_email_fabricator.rb index 47e158addbd..d91f6a9e399 100644 --- a/spec/fabricators/incoming_email_fabricator.rb +++ b/spec/fabricators/incoming_email_fabricator.rb @@ -1 +1,20 @@ -Fabricator(:incoming_email) +Fabricator(:incoming_email) do + message_id "12345@example.com" + subject "Hello world" + from_address "foo@example.com" + to_addresses "someone@else.com" + + raw <<~RAW + Return-Path: + From: Foo + To: someone@else.com + Subject: Hello world + Date: Fri, 15 Jan 2016 00:12:43 +0100 + Message-ID: <12345@example.com> + Mime-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: quoted-printable + + The body contains "Hello world" too. + RAW +end diff --git a/spec/fabricators/post_fabricator.rb b/spec/fabricators/post_fabricator.rb index 0854ba0db14..e566d949b81 100644 --- a/spec/fabricators/post_fabricator.rb +++ b/spec/fabricators/post_fabricator.rb @@ -133,3 +133,14 @@ Fabricator(:private_message_post, from: :post) do end raw "Ssshh! This is our secret conversation!" end + +Fabricator(:post_via_email, from: :post) do + incoming_email + via_email true + + after_create do |post| + incoming_email.topic = post.topic + incoming_email.post = post + incoming_email.user = post.user + end +end diff --git a/spec/services/post_alerter_spec.rb b/spec/services/post_alerter_spec.rb index 4293108b9b4..d7e655144b8 100644 --- a/spec/services/post_alerter_spec.rb +++ b/spec/services/post_alerter_spec.rb @@ -572,6 +572,61 @@ describe PostAlerter do expect(admin1.notifications.where(notification_type: Notification.types[:replied]).count).to eq(1) end + + it "sends email notifications only to users not on CC list of incoming email" do + alice = Fabricate(:user, username: "alice", email: "alice@example.com") + bob = Fabricate(:user, username: "bob", email: "bob@example.com") + carol = Fabricate(:user,username: "carol", email: "carol@example.com", staged: true) + dave = Fabricate(:user, username: "dave", email: "dave@example.com", staged: true) + erin = Fabricate(:user, username: "erin", email: "erin@example.com") + + topic = Fabricate(:private_message_topic, topic_allowed_users: [ + Fabricate.build(:topic_allowed_user, user: alice), + Fabricate.build(:topic_allowed_user, user: bob), + Fabricate.build(:topic_allowed_user, user: carol), + Fabricate.build(:topic_allowed_user, user: dave), + Fabricate.build(:topic_allowed_user, user: erin) + ]) + post = Fabricate(:post, user: alice, topic: topic) + + TopicUser.change(alice.id, topic.id, notification_level: TopicUser.notification_levels[:watching]) + TopicUser.change(bob.id, topic.id, notification_level: TopicUser.notification_levels[:watching]) + TopicUser.change(erin.id, topic.id, notification_level: TopicUser.notification_levels[:watching]) + + email = Fabricate(:incoming_email, + raw: <<~RAW, + Return-Path: + From: Bob + To: meta+1234@discoursemail.com, dave@example.com + CC: carol@example.com, erin@example.com + Subject: Hello world + Date: Fri, 15 Jan 2016 00:12:43 +0100 + Message-ID: <12345@example.com> + Mime-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: quoted-printable + + This post was created by email. + RAW + from_address: "bob@example.com", + to_addresses: "meta+1234@discoursemail.com;dave@example.com", + cc_addresses: "carol@example.com;erin@example.com") + reply = Fabricate(:post_via_email, user: bob, topic: topic, incoming_email: email, reply_to_post_number: 1) + + NotificationEmailer.expects(:process_notification).with { |n| n.user_id == alice.id }.once + NotificationEmailer.expects(:process_notification).with { |n| n.user_id == bob.id }.never + NotificationEmailer.expects(:process_notification).with { |n| n.user_id == carol.id }.never + NotificationEmailer.expects(:process_notification).with { |n| n.user_id == dave.id }.never + NotificationEmailer.expects(:process_notification).with { |n| n.user_id == erin.id }.never + + PostAlerter.post_created(reply) + + expect(alice.notifications.count).to eq(1) + expect(bob.notifications.count).to eq(0) + expect(carol.notifications.count).to eq(1) + expect(dave.notifications.count).to eq(1) + expect(erin.notifications.count).to eq(1) + end end context "watching" do