mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 22:43:33 +08:00
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:
@ -96,3 +96,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</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}}
|
||||||
|
@ -47,7 +47,7 @@ class Admin::EmailController < Admin::AdminController
|
|||||||
|
|
||||||
def handle_mail
|
def handle_mail
|
||||||
params.require(:email)
|
params.require(:email)
|
||||||
Email::Receiver.new(params[:email]).process
|
Email::Receiver.new(params[:email]).process!
|
||||||
render text: "email was processed"
|
render text: "email was processed"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -23,9 +23,14 @@ module Jobs
|
|||||||
def process_popmail(popmail)
|
def process_popmail(popmail)
|
||||||
begin
|
begin
|
||||||
mail_string = popmail.pop
|
mail_string = popmail.pop
|
||||||
Email::Receiver.new(mail_string).process
|
receiver = Email::Receiver.new(mail_string)
|
||||||
|
receiver.process!
|
||||||
rescue => e
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -49,6 +54,7 @@ module Jobs
|
|||||||
when ActiveRecord::Rollback then :email_reject_invalid_post
|
when ActiveRecord::Rollback then :email_reject_invalid_post
|
||||||
when Email::Receiver::InvalidPostAction then :email_reject_invalid_post_action
|
when Email::Receiver::InvalidPostAction then :email_reject_invalid_post_action
|
||||||
when Discourse::InvalidAccess then :email_reject_invalid_access
|
when Discourse::InvalidAccess then :email_reject_invalid_access
|
||||||
|
when RateLimiter::LimitExceeded then :email_reject_rate_limit_specified
|
||||||
end
|
end
|
||||||
|
|
||||||
template_args = {}
|
template_args = {}
|
||||||
@ -59,6 +65,10 @@ module Jobs
|
|||||||
template_args[:post_error] = e.message
|
template_args[:post_error] = e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if message_template == :email_reject_rate_limit_specified
|
||||||
|
template_args[:rate_limit_description] = e.description
|
||||||
|
end
|
||||||
|
|
||||||
if message_template
|
if message_template
|
||||||
# inform the user about the rejection
|
# inform the user about the rejection
|
||||||
message = Mail::Message.new(mail_string)
|
message = Mail::Message.new(mail_string)
|
||||||
@ -68,6 +78,8 @@ module Jobs
|
|||||||
|
|
||||||
client_message = RejectionMailer.send_rejection(message_template, message.from, template_args)
|
client_message = RejectionMailer.send_rejection(message_template, message.from, template_args)
|
||||||
Email::Sender.new(client_message, message_template).send
|
Email::Sender.new(client_message, message_template).send
|
||||||
|
|
||||||
|
client_message
|
||||||
else
|
else
|
||||||
Discourse.handle_job_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string))
|
Discourse.handle_job_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string))
|
||||||
end
|
end
|
||||||
|
@ -2,6 +2,7 @@ class IncomingEmailDetailsSerializer < ApplicationSerializer
|
|||||||
|
|
||||||
attributes :error,
|
attributes :error,
|
||||||
:error_description,
|
:error_description,
|
||||||
|
:rejection_message,
|
||||||
:return_path,
|
:return_path,
|
||||||
:date,
|
:date,
|
||||||
:from,
|
:from,
|
||||||
|
@ -2296,6 +2296,7 @@ en:
|
|||||||
cc: "Cc"
|
cc: "Cc"
|
||||||
subject: "Subject"
|
subject: "Subject"
|
||||||
body: "Body"
|
body: "Body"
|
||||||
|
rejection_message: "Rejection Mail"
|
||||||
filters:
|
filters:
|
||||||
from_placeholder: "from@example.com"
|
from_placeholder: "from@example.com"
|
||||||
to_placeholder: "to@example.com"
|
to_placeholder: "to@example.com"
|
||||||
|
@ -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."
|
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_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."
|
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."
|
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."
|
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_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."
|
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."
|
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:
|
hours:
|
||||||
one: "1 hour"
|
one: "1 hour"
|
||||||
@ -1885,6 +1889,13 @@ en:
|
|||||||
|
|
||||||
If you can correct the problem, please try again.
|
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:
|
email_reject_invalid_post_action:
|
||||||
subject_template: "[%{site_name}] Email issue -- Invalid Post Action"
|
subject_template: "[%{site_name}] Email issue -- Invalid Post Action"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddRejectionMessageToIncomingEmail < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :incoming_emails, :rejection_message, :text
|
||||||
|
end
|
||||||
|
end
|
@ -23,6 +23,8 @@ module Email
|
|||||||
class InvalidPost < ProcessingError; end
|
class InvalidPost < ProcessingError; end
|
||||||
class InvalidPostAction < ProcessingError; end
|
class InvalidPostAction < ProcessingError; end
|
||||||
|
|
||||||
|
attr_reader :incoming_email
|
||||||
|
|
||||||
def initialize(mail_string)
|
def initialize(mail_string)
|
||||||
raise EmptyEmailError if mail_string.blank?
|
raise EmptyEmailError if mail_string.blank?
|
||||||
@raw_email = mail_string
|
@raw_email = mail_string
|
||||||
@ -30,7 +32,7 @@ module Email
|
|||||||
raise NoMessageIdError if @mail.message_id.blank?
|
raise NoMessageIdError if @mail.message_id.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
def process
|
def process!
|
||||||
@from_email, @from_display_name = parse_from_field
|
@from_email, @from_display_name = parse_from_field
|
||||||
@incoming_email = find_or_create_incoming_email
|
@incoming_email = find_or_create_incoming_email
|
||||||
process_internal
|
process_internal
|
||||||
@ -40,12 +42,12 @@ module Email
|
|||||||
end
|
end
|
||||||
|
|
||||||
def find_or_create_incoming_email
|
def find_or_create_incoming_email
|
||||||
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |incoming_email|
|
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |ie|
|
||||||
incoming_email.raw = @raw_email
|
ie.raw = @raw_email
|
||||||
incoming_email.subject = subject
|
ie.subject = subject
|
||||||
incoming_email.from_address = @from_email
|
ie.from_address = @from_email
|
||||||
incoming_email.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
|
ie.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
|
||||||
incoming_email.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
|
ie.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ class RateLimiter
|
|||||||
end
|
end
|
||||||
|
|
||||||
def description
|
def description
|
||||||
|
|
||||||
time_left = ""
|
time_left = ""
|
||||||
if @available_in < 1.minute.to_i
|
if @available_in < 1.minute.to_i
|
||||||
time_left = I18n.t("rate_limiter.seconds", count: @available_in)
|
time_left = I18n.t("rate_limiter.seconds", count: @available_in)
|
||||||
@ -20,7 +19,7 @@ class RateLimiter
|
|||||||
end
|
end
|
||||||
|
|
||||||
if @type.present?
|
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: "")
|
msg = I18n.t("rate_limiter.by_type.#{type_key}", time_left: time_left, default: "")
|
||||||
return msg if msg.present?
|
return msg if msg.present?
|
||||||
end
|
end
|
||||||
|
@ -13,7 +13,7 @@ describe Email::Receiver do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def process(email_name)
|
def process(email_name)
|
||||||
Email::Receiver.new(email(email_name)).process
|
Email::Receiver.new(email(email_name)).process!
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an EmptyEmailError when 'mail_string' is blank" do
|
it "raises an EmptyEmailError when 'mail_string' is blank" do
|
||||||
|
Reference in New Issue
Block a user