2019-05-03 06:17:27 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2014-05-07 03:01:19 +08:00
|
|
|
# Builds a Mail::Message we can use for sending. Optionally supports using a template
|
2013-06-11 04:46:08 +08:00
|
|
|
# for the body and subject
|
|
|
|
module Email
|
|
|
|
class MessageBuilder
|
2013-07-23 02:20:41 +08:00
|
|
|
attr_reader :template_args
|
2013-06-11 04:46:08 +08:00
|
|
|
|
2020-04-30 14:48:34 +08:00
|
|
|
ALLOW_REPLY_BY_EMAIL_HEADER = 'X-Discourse-Allow-Reply-By-Email'
|
2018-07-18 16:28:44 +08:00
|
|
|
|
2017-07-28 09:20:09 +08:00
|
|
|
def initialize(to, opts = nil)
|
2013-06-11 04:46:08 +08:00
|
|
|
@to = to
|
|
|
|
@opts = opts || {}
|
2013-07-23 02:20:41 +08:00
|
|
|
|
2015-08-13 05:00:16 +08:00
|
|
|
@template_args = {
|
2017-03-21 21:11:15 +08:00
|
|
|
site_name: SiteSetting.title,
|
|
|
|
email_prefix: SiteSetting.email_prefix.presence || SiteSetting.title,
|
2015-08-13 05:00:16 +08:00
|
|
|
base_url: Discourse.base_url,
|
|
|
|
user_preferences_url: "#{Discourse.base_url}/my/preferences",
|
2016-06-03 21:48:54 +08:00
|
|
|
hostname: Discourse.current_hostname,
|
2015-08-13 05:00:16 +08:00
|
|
|
}.merge!(@opts)
|
2013-07-23 02:20:41 +08:00
|
|
|
|
|
|
|
if @template_args[:url].present?
|
2017-12-06 04:12:18 +08:00
|
|
|
@template_args[:header_instructions] ||= I18n.t('user_notifications.header_instructions', @template_args)
|
2015-12-08 05:52:10 +08:00
|
|
|
|
2014-05-07 03:01:19 +08:00
|
|
|
if @opts[:include_respond_instructions] == false
|
|
|
|
@template_args[:respond_instructions] = ''
|
2018-06-12 06:54:39 +08:00
|
|
|
@template_args[:respond_instructions] = I18n.t('user_notifications.pm_participants', @template_args) if @opts[:private_reply]
|
2014-05-07 03:01:19 +08:00
|
|
|
else
|
2016-02-27 06:56:56 +08:00
|
|
|
if @opts[:only_reply_by_email]
|
2019-05-03 06:17:27 +08:00
|
|
|
string = +"user_notifications.only_reply_by_email"
|
2018-06-12 06:54:39 +08:00
|
|
|
string << "_pm" if @opts[:private_reply]
|
2015-08-13 05:00:16 +08:00
|
|
|
else
|
2019-05-03 06:17:27 +08:00
|
|
|
string = allow_reply_by_email? ? +"user_notifications.reply_by_email" : +"user_notifications.visit_link_to_respond"
|
2016-02-27 06:56:56 +08:00
|
|
|
string << "_pm" if @opts[:private_reply]
|
2015-08-13 05:00:16 +08:00
|
|
|
end
|
2017-02-14 21:58:08 +08:00
|
|
|
@template_args[:respond_instructions] = "---\n" + I18n.t(string, @template_args)
|
2014-05-07 03:01:19 +08:00
|
|
|
end
|
2016-06-03 21:48:54 +08:00
|
|
|
|
|
|
|
if @opts[:add_unsubscribe_link]
|
|
|
|
unsubscribe_string = if @opts[:mailing_list_mode]
|
|
|
|
"unsubscribe_mailing_list"
|
|
|
|
elsif SiteSetting.unsubscribe_via_email_footer
|
|
|
|
"unsubscribe_link_and_mail"
|
|
|
|
else
|
|
|
|
"unsubscribe_link"
|
|
|
|
end
|
|
|
|
@template_args[:unsubscribe_instructions] = I18n.t(unsubscribe_string, @template_args)
|
|
|
|
end
|
2013-07-23 02:20:41 +08:00
|
|
|
end
|
2013-06-11 04:46:08 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def subject
|
2020-01-30 03:48:55 +08:00
|
|
|
if @opts[:template] &&
|
|
|
|
TranslationOverride.exists?(locale: I18n.locale, translation_key: "#{@opts[:template]}.subject_template")
|
|
|
|
subject = I18n.t("#{@opts[:template]}.subject_template", @template_args)
|
|
|
|
elsif @opts[:use_site_subject]
|
2014-09-29 13:16:55 +08:00
|
|
|
subject = String.new(SiteSetting.email_subject)
|
2017-06-21 23:22:10 +08:00
|
|
|
subject.gsub!("%{site_name}", @template_args[:email_prefix])
|
2019-01-18 17:52:48 +08:00
|
|
|
subject.gsub!("%{optional_re}", @opts[:add_re_to_subject] ? I18n.t('subject_re') : '')
|
2018-02-19 17:20:17 +08:00
|
|
|
subject.gsub!("%{optional_pm}", @opts[:private_reply] ? @template_args[:subject_pm] : '')
|
2014-10-03 19:44:08 +08:00
|
|
|
subject.gsub!("%{optional_cat}", @template_args[:show_category_in_subject] ? "[#{@template_args[:show_category_in_subject]}] " : '')
|
2018-07-11 10:24:07 +08:00
|
|
|
subject.gsub!("%{optional_tags}", @template_args[:show_tags_in_subject] ? "#{@template_args[:show_tags_in_subject]} " : '')
|
2014-09-29 13:16:55 +08:00
|
|
|
subject.gsub!("%{topic_title}", @template_args[:topic_title]) if @template_args[:topic_title] # must be last for safety
|
2019-01-18 17:52:48 +08:00
|
|
|
elsif @opts[:use_topic_title_subject]
|
|
|
|
subject = @opts[:add_re_to_subject] ? I18n.t('subject_re') : ''
|
|
|
|
subject = "#{subject}#{@template_args[:topic_title]}"
|
|
|
|
elsif @opts[:template]
|
|
|
|
subject = I18n.t("#{@opts[:template]}.subject_template", @template_args)
|
2014-09-29 13:16:55 +08:00
|
|
|
else
|
|
|
|
subject = @opts[:subject]
|
|
|
|
end
|
2013-06-11 04:46:08 +08:00
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2013-07-24 15:13:15 +08:00
|
|
|
def html_part
|
|
|
|
return unless html_override = @opts[:html_override]
|
|
|
|
|
2016-06-03 21:48:54 +08:00
|
|
|
if @template_args[:unsubscribe_instructions].present?
|
|
|
|
unsubscribe_instructions = PrettyText.cook(@template_args[:unsubscribe_instructions], sanitize: false).html_safe
|
|
|
|
html_override.gsub!("%{unsubscribe_instructions}", unsubscribe_instructions)
|
2015-11-24 23:58:26 +08:00
|
|
|
else
|
2016-06-03 21:48:54 +08:00
|
|
|
html_override.gsub!("%{unsubscribe_instructions}", "")
|
2015-11-24 23:58:26 +08:00
|
|
|
end
|
|
|
|
|
2016-06-03 21:48:54 +08:00
|
|
|
if @template_args[:header_instructions].present?
|
|
|
|
header_instructions = PrettyText.cook(@template_args[:header_instructions], sanitize: false).html_safe
|
2015-12-08 05:52:10 +08:00
|
|
|
html_override.gsub!("%{header_instructions}", header_instructions)
|
|
|
|
else
|
|
|
|
html_override.gsub!("%{header_instructions}", "")
|
|
|
|
end
|
|
|
|
|
2016-06-03 21:48:54 +08:00
|
|
|
if @template_args[:respond_instructions].present?
|
|
|
|
respond_instructions = PrettyText.cook(@template_args[:respond_instructions], sanitize: false).html_safe
|
2015-11-24 23:58:26 +08:00
|
|
|
html_override.gsub!("%{respond_instructions}", respond_instructions)
|
|
|
|
else
|
|
|
|
html_override.gsub!("%{respond_instructions}", "")
|
2013-07-24 15:13:15 +08:00
|
|
|
end
|
|
|
|
|
2019-10-10 05:50:48 +08:00
|
|
|
html = UserNotificationRenderer.render(
|
2019-07-31 03:05:08 +08:00
|
|
|
template: 'layouts/email_template',
|
|
|
|
format: :html,
|
|
|
|
locals: { html_body: html_override.html_safe }
|
|
|
|
)
|
2013-07-26 15:27:46 +08:00
|
|
|
|
2013-07-24 15:13:15 +08:00
|
|
|
Mail::Part.new do
|
|
|
|
content_type 'text/html; charset=UTF-8'
|
2019-07-31 03:05:08 +08:00
|
|
|
body html
|
2013-07-24 15:13:15 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-06-11 04:46:08 +08:00
|
|
|
def body
|
2019-04-30 08:25:53 +08:00
|
|
|
body = nil
|
|
|
|
|
|
|
|
if @opts[:template]
|
|
|
|
body = I18n.t("#{@opts[:template]}.text_body_template", template_args).dup
|
|
|
|
else
|
|
|
|
body = @opts[:body].dup
|
|
|
|
end
|
2013-06-11 04:46:08 +08:00
|
|
|
|
2016-06-03 21:48:54 +08:00
|
|
|
if @template_args[:unsubscribe_instructions].present?
|
2013-06-11 04:46:08 +08:00
|
|
|
body << "\n"
|
2016-06-03 21:48:54 +08:00
|
|
|
body << @template_args[:unsubscribe_instructions]
|
2013-06-11 04:46:08 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
body
|
|
|
|
end
|
|
|
|
|
|
|
|
def build_args
|
2016-06-03 21:48:54 +08:00
|
|
|
{
|
|
|
|
to: @to,
|
2013-06-14 05:00:00 +08:00
|
|
|
subject: subject,
|
|
|
|
body: body,
|
|
|
|
charset: 'UTF-8',
|
2016-06-03 21:48:54 +08:00
|
|
|
from: from_value
|
|
|
|
}
|
2013-06-11 04:46:08 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def header_args
|
|
|
|
result = {}
|
|
|
|
if @opts[:add_unsubscribe_link]
|
2016-07-14 04:32:46 +08:00
|
|
|
unsubscribe_url = @template_args[:unsubscribe_url].presence || @template_args[:user_preferences_url]
|
|
|
|
result['List-Unsubscribe'] = "<#{unsubscribe_url}>"
|
2016-04-07 22:21:17 +08:00
|
|
|
end
|
|
|
|
|
2016-07-14 04:32:46 +08:00
|
|
|
result['X-Discourse-Post-Id'] = @opts[:post_id].to_s if @opts[:post_id]
|
2013-06-19 03:54:02 +08:00
|
|
|
result['X-Discourse-Topic-Id'] = @opts[:topic_id].to_s if @opts[:topic_id]
|
2013-06-14 06:11:10 +08:00
|
|
|
|
2016-08-03 17:02:07 +08:00
|
|
|
# please, don't send us automatic responses...
|
|
|
|
result['X-Auto-Response-Suppress'] = 'All'
|
|
|
|
|
2013-06-14 05:00:00 +08:00
|
|
|
if allow_reply_by_email?
|
2018-07-18 16:28:44 +08:00
|
|
|
result[ALLOW_REPLY_BY_EMAIL_HEADER] = true
|
2013-06-14 05:00:00 +08:00
|
|
|
result['Reply-To'] = reply_by_email_address
|
|
|
|
else
|
|
|
|
result['Reply-To'] = from_value
|
|
|
|
end
|
2013-06-13 22:56:16 +08:00
|
|
|
|
2013-07-07 08:37:44 +08:00
|
|
|
result.merge(MessageBuilder.custom_headers(SiteSetting.email_custom_headers))
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.custom_headers(string)
|
|
|
|
result = {}
|
|
|
|
string.split('|').each { |item|
|
|
|
|
header = item.split(':', 2)
|
|
|
|
if header.length == 2
|
|
|
|
name = header[0].strip
|
|
|
|
value = header[1].strip
|
|
|
|
result[name] = value if name.length > 0 && value.length > 0
|
|
|
|
end
|
2013-07-10 21:47:38 +08:00
|
|
|
} unless string.nil?
|
2013-06-11 04:46:08 +08:00
|
|
|
result
|
|
|
|
end
|
|
|
|
|
2013-06-14 05:00:00 +08:00
|
|
|
protected
|
|
|
|
|
|
|
|
def allow_reply_by_email?
|
|
|
|
SiteSetting.reply_by_email_enabled? &&
|
|
|
|
reply_by_email_address.present? &&
|
|
|
|
@opts[:allow_reply_by_email]
|
|
|
|
end
|
|
|
|
|
2014-06-06 21:09:00 +08:00
|
|
|
def private_reply?
|
2015-02-06 19:08:37 +08:00
|
|
|
allow_reply_by_email? && @opts[:private_reply]
|
2014-06-06 21:09:00 +08:00
|
|
|
end
|
|
|
|
|
2013-06-14 05:00:00 +08:00
|
|
|
def from_value
|
|
|
|
return @from_value if @from_value
|
|
|
|
@from_value = @opts[:from] || SiteSetting.notification_email
|
|
|
|
@from_value = alias_email(@from_value)
|
|
|
|
end
|
|
|
|
|
|
|
|
def reply_by_email_address
|
|
|
|
return @reply_by_email_address if @reply_by_email_address
|
|
|
|
return nil unless SiteSetting.reply_by_email_address.present?
|
|
|
|
|
|
|
|
@reply_by_email_address = SiteSetting.reply_by_email_address.dup
|
2017-07-28 09:20:09 +08:00
|
|
|
|
|
|
|
@reply_by_email_address =
|
|
|
|
if private_reply?
|
|
|
|
alias_email(@reply_by_email_address)
|
|
|
|
else
|
|
|
|
site_alias_email(@reply_by_email_address)
|
|
|
|
end
|
2013-06-14 05:00:00 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def alias_email(source)
|
2017-02-28 03:22:56 +08:00
|
|
|
return source if @opts[:from_alias].blank? &&
|
|
|
|
SiteSetting.email_site_title.blank? &&
|
|
|
|
SiteSetting.title.blank?
|
|
|
|
|
2019-01-04 23:06:21 +08:00
|
|
|
if @opts[:from_alias].present?
|
|
|
|
%Q|"#{Email.cleanup_alias(@opts[:from_alias])}" <#{source}>|
|
2017-02-28 03:22:56 +08:00
|
|
|
elsif source == SiteSetting.notification_email || source == SiteSetting.reply_by_email_address
|
|
|
|
site_alias_email(source)
|
2014-07-23 03:52:14 +08:00
|
|
|
else
|
2017-02-28 03:22:56 +08:00
|
|
|
source
|
2014-07-23 03:52:14 +08:00
|
|
|
end
|
2013-06-14 05:00:00 +08:00
|
|
|
end
|
|
|
|
|
2014-06-06 21:09:00 +08:00
|
|
|
def site_alias_email(source)
|
2019-01-04 23:06:21 +08:00
|
|
|
from_alias = Email.site_title
|
|
|
|
%Q|"#{Email.cleanup_alias(from_alias)}" <#{source}>|
|
2014-06-06 21:09:00 +08:00
|
|
|
end
|
|
|
|
|
2013-06-11 04:46:08 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|