mirror of
https://github.com/discourse/discourse.git
synced 2025-05-24 03:36:18 +08:00
FEATURE: allow users to easily track/watch/mute topics via email
If you reply to an email with the word "mute" a topic will be muted If you reply to an email with the word "track" a topic will be tracked If you reply to an email with the word "watch" a topic will be watched These ninja command can help advanced mailing list ex-users, saves a trip to the website
This commit is contained in:
@ -899,6 +899,22 @@ module Email
|
|||||||
create_post_with_attachments(options)
|
create_post_with_attachments(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notification_level_for(body)
|
||||||
|
# since we are stripping save all this work on long replies
|
||||||
|
return nil if body.length > 40
|
||||||
|
|
||||||
|
body = body.strip.downcase
|
||||||
|
case body
|
||||||
|
when "mute"
|
||||||
|
NotificationLevels.topic_levels[:muted]
|
||||||
|
when "track"
|
||||||
|
NotificationLevels.topic_levels[:tracking]
|
||||||
|
when "watch"
|
||||||
|
NotificationLevels.topic_levels[:watching]
|
||||||
|
else nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def create_reply(options = {})
|
def create_reply(options = {})
|
||||||
raise TopicNotFoundError if options[:topic].nil? || options[:topic].trashed?
|
raise TopicNotFoundError if options[:topic].nil? || options[:topic].trashed?
|
||||||
raise BouncedEmailError if options[:bounce] && options[:topic].archetype != Archetype.private_message
|
raise BouncedEmailError if options[:bounce] && options[:topic].archetype != Archetype.private_message
|
||||||
@ -908,6 +924,8 @@ module Email
|
|||||||
|
|
||||||
if post_action_type = post_action_for(options[:raw])
|
if post_action_type = post_action_for(options[:raw])
|
||||||
create_post_action(options[:user], options[:post], post_action_type)
|
create_post_action(options[:user], options[:post], post_action_type)
|
||||||
|
elsif notification_level = notification_level_for(options[:raw])
|
||||||
|
TopicUser.change(options[:user].id, options[:post].topic_id, notification_level: notification_level)
|
||||||
else
|
else
|
||||||
raise TopicClosedError if options[:topic].closed?
|
raise TopicClosedError if options[:topic].closed?
|
||||||
options[:topic_id] = options[:topic].id
|
options[:topic_id] = options[:topic].id
|
||||||
|
@ -251,6 +251,10 @@ describe Email::Receiver do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let :topic_user do
|
||||||
|
TopicUser.find_by(topic_id: topic.id, user_id: user.id)
|
||||||
|
end
|
||||||
|
|
||||||
it "uses MD5 of 'mail_string' there is no message_id" do
|
it "uses MD5 of 'mail_string' there is no message_id" do
|
||||||
mail_string = email(:missing_message_id)
|
mail_string = email(:missing_message_id)
|
||||||
expect { Email::Receiver.new(mail_string).process! }.to change { IncomingEmail.count }
|
expect { Email::Receiver.new(mail_string).process! }.to change { IncomingEmail.count }
|
||||||
@ -285,14 +289,34 @@ describe Email::Receiver do
|
|||||||
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicNotFoundError)
|
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicNotFoundError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a TopicClosedError when the topic was closed" do
|
context "a closed topic" do
|
||||||
|
|
||||||
|
before do
|
||||||
topic.update_columns(closed: true)
|
topic.update_columns(closed: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises a TopicClosedError when the topic was closed" do
|
||||||
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicClosedError)
|
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicClosedError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not raise TopicClosedError when performing a like action" do
|
it "Can watch topics via the watch command" do
|
||||||
|
# TODO support other locales as well, the tricky thing is that these string live in
|
||||||
|
# client.yml not on server yml so it is a bit tricky to find
|
||||||
|
|
||||||
topic.update_columns(closed: true)
|
topic.update_columns(closed: true)
|
||||||
expect { process(:like) }.to change(PostAction, :count)
|
process(:watch)
|
||||||
|
expect(topic_user.notification_level).to eq(NotificationLevels.topic_levels[:watching])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Can mute topics via the mute command" do
|
||||||
|
process(:mute)
|
||||||
|
expect(topic_user.notification_level).to eq(NotificationLevels.topic_levels[:muted])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can track a topic via the track command" do
|
||||||
|
process(:track)
|
||||||
|
expect(topic_user.notification_level).to eq(NotificationLevels.topic_levels[:tracking])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an InvalidPost when there was an error while creating the post" do
|
it "raises an InvalidPost when there was an error while creating the post" do
|
||||||
|
10
spec/fixtures/emails/mute.eml
vendored
Normal file
10
spec/fixtures/emails/mute.eml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <13@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
mute
|
10
spec/fixtures/emails/track.eml
vendored
Normal file
10
spec/fixtures/emails/track.eml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <13@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
track
|
10
spec/fixtures/emails/watch.eml
vendored
Normal file
10
spec/fixtures/emails/watch.eml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <13@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
watch
|
Reference in New Issue
Block a user