add support for incoming emails in CC/BCC fields
This commit is contained in:
parent
6c2dee29a8
commit
93d1cc6294
|
@ -14,9 +14,7 @@ module Jobs
|
|||
|
||||
def execute(args)
|
||||
@args = args
|
||||
if SiteSetting.pop3_polling_enabled?
|
||||
poll_pop3
|
||||
end
|
||||
poll_pop3 if SiteSetting.pop3_polling_enabled?
|
||||
end
|
||||
|
||||
def handle_mail(mail)
|
||||
|
@ -31,7 +29,6 @@ module Jobs
|
|||
end
|
||||
|
||||
def handle_failure(mail_string, e)
|
||||
|
||||
Rails.logger.warn("Email can not be processed: #{e}\n\n#{mail_string}") if SiteSetting.log_mail_processing_failures
|
||||
|
||||
template_args = {}
|
||||
|
@ -90,14 +87,14 @@ module Jobs
|
|||
|
||||
connection.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
|
||||
unless pop.mails.empty?
|
||||
pop.each do |mail|
|
||||
handle_mail(mail)
|
||||
end
|
||||
pop.each { |mail| handle_mail(mail) }
|
||||
end
|
||||
pop.finish
|
||||
end
|
||||
rescue Net::POPAuthenticationError => e
|
||||
Discourse.handle_job_exception(e, error_context(@args, "Signing in to poll incoming email"))
|
||||
rescue Net::POPError => e
|
||||
Discourse.handle_job_exception(e, error_context(@args, "Generic POP error"))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,19 +10,25 @@ class EmailLog < ActiveRecord::Base
|
|||
|
||||
after_create do
|
||||
# Update last_emailed_at if the user_id is present and email was sent
|
||||
User.where(id: user_id).update_all("last_emailed_at = CURRENT_TIMESTAMP") if user_id.present? and !skipped
|
||||
User.where(id: user_id).update_all("last_emailed_at = CURRENT_TIMESTAMP") if user_id.present? && !skipped
|
||||
end
|
||||
|
||||
def self.count_per_day(start_date, end_date)
|
||||
where('created_at >= ? and created_at < ? AND skipped = false', start_date, end_date).group('date(created_at)').order('date(created_at)').count
|
||||
sent.where("created_at BETWEEN ? AND ?", start_date, end_date)
|
||||
.group("DATE(created_at)")
|
||||
.order("DATE(created_at)")
|
||||
.count
|
||||
end
|
||||
|
||||
def self.for(reply_key)
|
||||
EmailLog.find_by(reply_key: reply_key)
|
||||
self.find_by(reply_key: reply_key)
|
||||
end
|
||||
|
||||
def self.last_sent_email_address
|
||||
where(email_type: 'signup').order('created_at DESC').first.try(:to_address)
|
||||
self.where(email_type: "signup")
|
||||
.order(created_at: :desc)
|
||||
.first
|
||||
.try(:to_address)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -34,7 +34,8 @@ module Email
|
|||
body = parse_body(message)
|
||||
|
||||
dest_info = { type: :invalid, obj: nil }
|
||||
message.to.each do |to_address|
|
||||
# 'smtp_envelope_to' is a combination of: to, cc and bcc fields
|
||||
message.smtp_envelope_to.each do |to_address|
|
||||
dest_info = check_address(to_address)
|
||||
break if dest_info[:type] != :invalid
|
||||
end
|
||||
|
@ -51,7 +52,6 @@ module Email
|
|||
|
||||
case dest_info[:type]
|
||||
when :group
|
||||
raise BadDestinationAddress unless SiteSetting.email_in
|
||||
group = dest_info[:obj]
|
||||
|
||||
if @user.blank?
|
||||
|
@ -68,7 +68,6 @@ module Email
|
|||
|
||||
create_new_topic(archetype: Archetype.private_message, target_group_names: [group.name])
|
||||
when :category
|
||||
raise BadDestinationAddress unless SiteSetting.email_in
|
||||
category = dest_info[:obj]
|
||||
|
||||
if @user.blank? && category.email_in_allow_strangers
|
||||
|
@ -108,11 +107,14 @@ module Email
|
|||
end
|
||||
|
||||
def check_address(address)
|
||||
# only check groups/categories when 'email_in' is enabled
|
||||
if SiteSetting.email_in
|
||||
group = Group.find_by_email(address)
|
||||
return { type: :group, obj: group } if group
|
||||
|
||||
category = Category.find_by_email(address)
|
||||
return { type: :category, obj: category } if category
|
||||
end
|
||||
|
||||
regex = Regexp.escape(SiteSetting.reply_by_email_address)
|
||||
regex = regex.gsub(Regexp.escape('%{reply_key}'), "(.*)")
|
||||
|
|
|
@ -474,16 +474,17 @@ This is a link http://example.com"
|
|||
|
||||
end
|
||||
|
||||
def fill_email(mail, from, to, body = nil, subject = nil)
|
||||
def fill_email(mail, from, to, body = nil, subject = nil, cc = nil)
|
||||
result = mail.gsub("FROM", from).gsub("TO", to)
|
||||
result.gsub!(/Hey.*/m, body) if body
|
||||
result.sub!(/We .*/, subject) if subject
|
||||
result.sub!("CC", cc.presence || "")
|
||||
result
|
||||
end
|
||||
|
||||
def process_email(opts)
|
||||
incoming_email = fixture_file("emails/valid_incoming.eml")
|
||||
email = fill_email(incoming_email, opts[:from], opts[:to], opts[:body], opts[:subject])
|
||||
email = fill_email(incoming_email, opts[:from], opts[:to], opts[:body], opts[:subject], opts[:cc])
|
||||
Email::Receiver.new(email).process
|
||||
end
|
||||
|
||||
|
@ -532,15 +533,15 @@ greatest show ever created. Everyone should watch it.
|
|||
end
|
||||
|
||||
describe "processes an email to a category" do
|
||||
let(:to) { "some@email.com" }
|
||||
|
||||
before do
|
||||
SiteSetting.email_in = true
|
||||
SiteSetting.email_in_min_trust = TrustLevel[4].to_s
|
||||
end
|
||||
|
||||
it "correctly can target categories" do
|
||||
to = "some@email.com"
|
||||
|
||||
Fabricate(:category, email_in_allow_strangers: false, email_in: to)
|
||||
SiteSetting.email_in_min_trust = TrustLevel[4].to_s
|
||||
|
||||
# no email in for user
|
||||
expect{
|
||||
|
@ -614,7 +615,7 @@ greatest show ever created. Everyone should watch it.
|
|||
}.to raise_error(Email::Receiver::UserNotFoundError)
|
||||
end
|
||||
|
||||
it "creates a topic for allowed category" do
|
||||
it "creates a topic for matching category" do
|
||||
Fabricate(:category, email_in_allow_strangers: true, email_in: email_in)
|
||||
process_email(from: user_email, to: email_in, body: body)
|
||||
|
||||
|
@ -636,7 +637,7 @@ greatest show ever created. Everyone should watch it.
|
|||
SiteSetting.allow_staged_accounts = true
|
||||
end
|
||||
|
||||
it "creates a message for allowed group" do
|
||||
it "creates a message for matching group" do
|
||||
Fabricate(:group, incoming_email: incoming_email)
|
||||
process_email(from: user_email, to: incoming_email, body: body)
|
||||
|
||||
|
@ -652,4 +653,31 @@ greatest show ever created. Everyone should watch it.
|
|||
|
||||
end
|
||||
|
||||
describe "supports incoming mail in CC fields" do
|
||||
|
||||
let(:incoming_email) { "foo@bar.com" }
|
||||
let(:user_email) { "#{SecureRandom.hex(32)}@foobar.com" }
|
||||
let(:body) { "This is a message to\n\na group via CC ;)" }
|
||||
|
||||
before do
|
||||
SiteSetting.email_in = true
|
||||
SiteSetting.allow_staged_accounts = true
|
||||
end
|
||||
|
||||
it "creates a message for matching group" do
|
||||
Fabricate(:group, incoming_email: incoming_email)
|
||||
process_email(from: user_email, to: "some@email.com", body: body, cc: incoming_email)
|
||||
|
||||
staged_account = User.find_by_email(user_email)
|
||||
expect(staged_account).to be
|
||||
expect(staged_account.staged).to be(true)
|
||||
|
||||
post = staged_account.posts.order(id: :desc).first
|
||||
expect(post).to be
|
||||
expect(post.raw).to eq(body)
|
||||
expect(post.topic.private_message?).to eq(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ 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 <FROM>
|
||||
To: <TO>
|
||||
Cc: <CC>
|
||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
||||
Subject: We should have a post-by-email-feature.
|
||||
Mime-Version: 1.0
|
||||
|
|
Loading…
Reference in New Issue