FEATURE: Add rejection message on rejected IncomingEmail

FIX: Better RateLimit description in rejected IncomingEmail
FEATURE: Send email when hitting a rate limit
This commit is contained in:
Régis Hanol 2016-03-07 16:56:17 +01:00
parent 090a064c41
commit 622d804d46
10 changed files with 56 additions and 13 deletions

View File

@ -96,3 +96,15 @@
</div>
</div>
{{#if model.rejection_message}}
<hr>
<div class="control-group">
<label>{{i18n "admin.email.incoming_emails.modal.rejection_message"}}</label>
<div class="controls">
{{textarea value=model.rejection_message}}
</div>
</div>
{{/if}}

View File

@ -47,7 +47,7 @@ class Admin::EmailController < Admin::AdminController
def handle_mail
params.require(:email)
Email::Receiver.new(params[:email]).process
Email::Receiver.new(params[:email]).process!
render text: "email was processed"
end

View File

@ -23,9 +23,14 @@ module Jobs
def process_popmail(popmail)
begin
mail_string = popmail.pop
Email::Receiver.new(mail_string).process
receiver = Email::Receiver.new(mail_string)
receiver.process!
rescue => e
handle_failure(mail_string, e)
rejection_message = handle_failure(mail_string, e)
if rejection_message.present? && receiver && receiver.incoming_email
receiver.incoming_email.rejection_message = rejection_message.body.to_s
receiver.incoming_email.save
end
end
end
@ -49,6 +54,7 @@ module Jobs
when ActiveRecord::Rollback then :email_reject_invalid_post
when Email::Receiver::InvalidPostAction then :email_reject_invalid_post_action
when Discourse::InvalidAccess then :email_reject_invalid_access
when RateLimiter::LimitExceeded then :email_reject_rate_limit_specified
end
template_args = {}
@ -59,6 +65,10 @@ module Jobs
template_args[:post_error] = e.message
end
if message_template == :email_reject_rate_limit_specified
template_args[:rate_limit_description] = e.description
end
if message_template
# inform the user about the rejection
message = Mail::Message.new(mail_string)
@ -68,6 +78,8 @@ module Jobs
client_message = RejectionMailer.send_rejection(message_template, message.from, template_args)
Email::Sender.new(client_message, message_template).send
client_message
else
Discourse.handle_job_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string))
end

View File

@ -2,6 +2,7 @@ class IncomingEmailDetailsSerializer < ApplicationSerializer
attributes :error,
:error_description,
:rejection_message,
:return_path,
:date,
:from,

View File

@ -2296,6 +2296,7 @@ en:
cc: "Cc"
subject: "Subject"
body: "Body"
rejection_message: "Rejection Mail"
filters:
from_placeholder: "from@example.com"
to_placeholder: "to@example.com"

View File

@ -406,11 +406,15 @@ en:
first_day_topics_per_day: "You've reached the maximum number of topics a new user can create on their first day. Please wait %{time_left} before trying again."
create_topic: "You're creating topics too quickly. Please wait %{time_left} before trying again."
create_post: "You're replying too quickly. Please wait %{time_left} before trying again."
delete_post: "You're deleting posts too quickly. Please wait %{time_left} before trying again."
topics_per_day: "You've reached the maximum number of new topics today. Please wait %{time_left} before trying again."
pms_per_day: "You've reached the maximum number of messages today. Please wait %{time_left} before trying again."
create_like: "You've reached the maximum number of likes today. Please wait %{time_left} before trying again."
create_bookmark: "You've reached the maximum number of bookmarks today. Please wait %{time_left} before trying again."
edit_post: "You've reached the maximun number of edits today. Please wait %{time_left} before trying again."
live_post_counts: "You've asking for live post counts too quickly. Please wait %{time_left} before trying again."
unsubscribe_via_email: "You've reached the maximum number of unsubscribe via email today. Please wait %{time_left} before trying again."
topic_invitations_per_day: "You've reached the maximum number of topic invitations today. Please wait %{time_left} before trying again."
hours:
one: "1 hour"
@ -1885,6 +1889,13 @@ en:
If you can correct the problem, please try again.
email_reject_rate_limit_specified:
subject_template: "[%{site_name}] Email issue -- Rate limited"
text_body_template: |
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
Reason: %{rate_limit_description}
email_reject_invalid_post_action:
subject_template: "[%{site_name}] Email issue -- Invalid Post Action"
text_body_template: |

View File

@ -0,0 +1,5 @@
class AddRejectionMessageToIncomingEmail < ActiveRecord::Migration
def change
add_column :incoming_emails, :rejection_message, :text
end
end

View File

@ -23,6 +23,8 @@ module Email
class InvalidPost < ProcessingError; end
class InvalidPostAction < ProcessingError; end
attr_reader :incoming_email
def initialize(mail_string)
raise EmptyEmailError if mail_string.blank?
@raw_email = mail_string
@ -30,7 +32,7 @@ module Email
raise NoMessageIdError if @mail.message_id.blank?
end
def process
def process!
@from_email, @from_display_name = parse_from_field
@incoming_email = find_or_create_incoming_email
process_internal
@ -40,12 +42,12 @@ module Email
end
def find_or_create_incoming_email
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |incoming_email|
incoming_email.raw = @raw_email
incoming_email.subject = subject
incoming_email.from_address = @from_email
incoming_email.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
incoming_email.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |ie|
ie.raw = @raw_email
ie.subject = subject
ie.from_address = @from_email
ie.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
ie.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
end
end

View File

@ -9,7 +9,6 @@ class RateLimiter
end
def description
time_left = ""
if @available_in < 1.minute.to_i
time_left = I18n.t("rate_limiter.seconds", count: @available_in)
@ -20,7 +19,7 @@ class RateLimiter
end
if @type.present?
type_key = @type.gsub(/-/, '_')
type_key = @type.tr("-", "_")
msg = I18n.t("rate_limiter.by_type.#{type_key}", time_left: time_left, default: "")
return msg if msg.present?
end

View File

@ -13,7 +13,7 @@ describe Email::Receiver do
end
def process(email_name)
Email::Receiver.new(email(email_name)).process
Email::Receiver.new(email(email_name)).process!
end
it "raises an EmptyEmailError when 'mail_string' is blank" do