mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
Refactor and clean up New-Topic via Email
With the new email_in admin configuration setting, emails to the email_in_address fetched via POP will now be processed and posted as new topics to the forum. With the email_in_min_trust you can control the trust level the user needs to have at least to be able to post an email as a new topic. Also contains tests for the email-in feature and minor clean ups
This commit is contained in:
parent
dad43b9853
commit
4af2cf3f23
7 changed files with 164 additions and 42 deletions
|
@ -90,11 +90,3 @@ cors_origin = '*'
|
|||
|
||||
# enable if you really need to serve assets in prd
|
||||
serve_static_assets = false
|
||||
|
||||
# Enable new topic creation via email by setting this value to "true"
|
||||
allow_new_topics_from_email =
|
||||
|
||||
# Set the default category for new threads by entering the category number here
|
||||
default_categories_id =
|
||||
|
||||
|
||||
|
|
|
@ -791,6 +791,10 @@ en:
|
|||
pop3s_polling_host: "The host to poll for email via POP3S"
|
||||
pop3s_polling_username: "The username for the POP3S account to poll for email"
|
||||
pop3s_polling_password: "The password for the POP3S account to poll for email"
|
||||
email_in: "Allow users to post new topics via email"
|
||||
email_in_address: "The email address the users can post new topics to. None means users can't post globally."
|
||||
email_in_min_trust: "The minimum trust level an users needs to have to be allowed to post new topics via email"
|
||||
email_in_category: "The category new emails are posted into"
|
||||
enable_mailing_list_mode: "Allow users to (optionally) opt-in to mailing list mode via a user preference"
|
||||
|
||||
minimum_topics_similar: "How many topics need to exist in the database before similar topics are presented."
|
||||
|
|
|
@ -235,6 +235,12 @@ email:
|
|||
pop3s_polling_port: 995
|
||||
pop3s_polling_username: ''
|
||||
pop3s_polling_password: ''
|
||||
email_in: false
|
||||
email_in_address: ''
|
||||
email_in_min_trust:
|
||||
default: 3
|
||||
enum: 'MinTrustToCreateTopicSetting'
|
||||
email_in_category: -1
|
||||
enable_mailing_list_mode:
|
||||
default: false
|
||||
client: true
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
## App Setup
|
||||
> TODO build an admin UI for this, get it out of discourse_defaults.conf
|
||||
|
||||
Enable new topic creation via email by setting this value to "true"
|
||||
`allow_new_topics_from_email = `
|
||||
|
||||
Set the default category for new threads by entering the category number here
|
||||
`default_categories_id = `
|
||||
|
||||
|
||||
## Admin UI Setup
|
||||
|
||||
|
|
|
@ -31,6 +31,15 @@ module Email
|
|||
discourse_email_parser
|
||||
|
||||
return Email::Receiver.results[:unprocessable] if @body.blank?
|
||||
|
||||
if SiteSetting.email_in and @message.to.first == SiteSetting.email_in_address
|
||||
@user = User.find_by_email(@message.from.first)
|
||||
return Email::Receiver.results[:unprocessable] if @user.blank? or not @user.has_trust_level?(TrustLevel.levels[SiteSetting.email_in_min_trust.to_i])
|
||||
|
||||
create_new_topic
|
||||
return Email::Receiver.results[:processed]
|
||||
end
|
||||
|
||||
@reply_key = @message.to.first
|
||||
|
||||
# Extract the `reply_key` from the format the site has specified
|
||||
|
@ -39,19 +48,12 @@ module Email
|
|||
@reply_key.gsub!(t, "") if t.present?
|
||||
end
|
||||
|
||||
# Look up the email log for the reply key, or create a new post if there is none
|
||||
# Enabled when config/discourse.conf contains "allow_new_topics_from_email = true"
|
||||
# Look up the email log for the reply key
|
||||
@email_log = EmailLog.for(reply_key)
|
||||
if @email_log.blank?
|
||||
return Email::Receiver.results[:unprocessable] if GlobalSetting.allow_new_topics_from_email == false
|
||||
@subject = @message.subject
|
||||
@user_info = User.find_by_email(@message.from.first)
|
||||
return Email::Receiver.results[:unprocessable] if @user_info.blank?
|
||||
Rails.logger.debug "Creating post from #{@message.from.first} with subject #{@subject}"
|
||||
create_new
|
||||
else
|
||||
create_reply
|
||||
end
|
||||
return Email::Receiver.results[:missing] if @email_log.blank?
|
||||
|
||||
create_reply
|
||||
|
||||
Email::Receiver.results[:processed]
|
||||
rescue
|
||||
Email::Receiver.results[:error]
|
||||
|
@ -137,20 +139,25 @@ module Email
|
|||
|
||||
creator.create
|
||||
end
|
||||
def create_new
|
||||
# Try to create a new topic with the body and subject
|
||||
# looking to config/discourse.conf to set category
|
||||
if defined? GlobalSetting.default_categories_id
|
||||
@categoryID = 1
|
||||
else
|
||||
@categoryID = GlobalSetting.default_categories_id
|
||||
end
|
||||
creator = PostCreator.new(@user_info,
|
||||
title: @subject,
|
||||
raw: @body,
|
||||
category: @categoryID,
|
||||
cooking_options: {traditional_markdown_linebreaks: true})
|
||||
creator.create
|
||||
|
||||
def create_new_topic
|
||||
# Try to post the body as a reply
|
||||
topic_creator = TopicCreator.new(@user,
|
||||
Guardian.new(@user),
|
||||
category: SiteSetting.email_in_category.to_i,
|
||||
title: @message.subject)
|
||||
|
||||
topic = topic_creator.create
|
||||
post_creator = PostCreator.new(@user,
|
||||
raw: @body,
|
||||
topic_id: topic.id,
|
||||
cooking_options: {traditional_markdown_linebreaks: true})
|
||||
|
||||
post_creator.create
|
||||
EmailLog.create(email_type: "topic_via_incoming_email",
|
||||
to_address: SiteSetting.email_in_address,
|
||||
topic_id: topic.id, user_id: @user.id)
|
||||
topic
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ describe Email::Receiver do
|
|||
|
||||
before do
|
||||
SiteSetting.stubs(:reply_by_email_address).returns("reply+%{reply_key}@appmail.adventuretime.ooo")
|
||||
SiteSetting.stubs(:email_in).returns(false)
|
||||
end
|
||||
|
||||
describe "exception raised" do
|
||||
|
@ -204,5 +205,100 @@ greatest show ever created. Everyone should watch it.
|
|||
|
||||
end
|
||||
|
||||
describe "processes a valid incoming email" do
|
||||
before do
|
||||
SiteSetting.stubs(:email_in_address).returns("discourse-in@appmail.adventuretime.ooo")
|
||||
SiteSetting.stubs(:email_in_category).returns("42")
|
||||
SiteSetting.stubs(:email_in).returns(true)
|
||||
end
|
||||
|
||||
let(:incoming_email) { File.read("#{Rails.root}/spec/fixtures/emails/valid_incoming.eml") }
|
||||
let(:receiver) { Email::Receiver.new(incoming_email) }
|
||||
let(:user) { Fabricate.build(:user, id: 3456) }
|
||||
let(:subject) { "We should have a post-by-email-feature." }
|
||||
let(:email_body) {
|
||||
"Hey folks,
|
||||
|
||||
I was thinking. Wouldn't it be great if we could post topics via email? Yes it would!
|
||||
|
||||
Jakie" }
|
||||
|
||||
describe "email from non user" do
|
||||
|
||||
before do
|
||||
User.expects(:find_by_email).returns(nil)
|
||||
end
|
||||
|
||||
let!(:result) { receiver.process }
|
||||
|
||||
it "returns unprocessable" do
|
||||
expect(result).to eq(Email::Receiver.results[:unprocessable])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "email from untrusted user" do
|
||||
before do
|
||||
User.expects(:find_by_email).with(
|
||||
"jake@adventuretime.ooo").returns(user)
|
||||
SiteSetting.stubs(:email_in_min_trust).returns(TrustLevel.levels[:elder].to_s)
|
||||
end
|
||||
|
||||
let!(:result) { receiver.process }
|
||||
|
||||
it "returns unprocessable" do
|
||||
expect(result).to eq(Email::Receiver.results[:unprocessable])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "with proper user" do
|
||||
|
||||
before do
|
||||
SiteSetting.stubs(:email_in_min_trust).returns(TrustLevel.levels[:newuser].to_s)
|
||||
User.expects(:find_by_email).with(
|
||||
"jake@adventuretime.ooo").returns(user)
|
||||
|
||||
topic_creator = mock()
|
||||
TopicCreator.expects(:new).with(instance_of(User),
|
||||
instance_of(Guardian),
|
||||
has_entries(title: subject,
|
||||
category: 42))
|
||||
.returns(topic_creator)
|
||||
|
||||
topic_creator.expects(:create).returns(topic_creator)
|
||||
topic_creator.expects(:id).twice.returns(12345)
|
||||
|
||||
|
||||
post_creator = mock
|
||||
PostCreator.expects(:new).with(instance_of(User),
|
||||
has_entries(raw: email_body,
|
||||
topic_id: 12345,
|
||||
cooking_options: {traditional_markdown_linebreaks: true}))
|
||||
.returns(post_creator)
|
||||
|
||||
post_creator.expects(:create)
|
||||
|
||||
EmailLog.expects(:create).with(has_entries(
|
||||
email_type: 'topic_via_incoming_email',
|
||||
to_address: "discourse-in@appmail.adventuretime.ooo",
|
||||
user_id: 3456,
|
||||
topic_id: 12345
|
||||
))
|
||||
end
|
||||
|
||||
let!(:result) { receiver.process }
|
||||
|
||||
it "returns a processed result" do
|
||||
expect(result).to eq(Email::Receiver.results[:processed])
|
||||
end
|
||||
|
||||
it "extracts the body" do
|
||||
expect(receiver.body).to eq(email_body)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
25
spec/fixtures/emails/valid_incoming.eml
vendored
Normal file
25
spec/fixtures/emails/valid_incoming.eml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
Return-Path: <jake@adventuretime.ooo>
|
||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <discourse-in@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
|
||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <discourse-in@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
|
||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
||||
From: Jake the Dog <jake@adventuretime.ooo>
|
||||
To: discourse-in@appmail.adventuretime.ooo
|
||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
||||
Subject: We should have a post-by-email-feature.
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain;
|
||||
charset=ISO-8859-1
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Sieve: CMU Sieve 2.2
|
||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
||||
|
||||
Hey folks,
|
||||
|
||||
I was thinking. Wouldn't it be great if we could post topics via email? Yes it would!
|
||||
|
||||
Jakie
|
||||
|
Loading…
Reference in a new issue