discourse/app/jobs/regular/user_email.rb

152 lines
5.0 KiB
Ruby
Raw Normal View History

2013-06-10 15:33:37 -04:00
require_dependency 'email/sender'
2013-02-05 14:16:51 -05:00
module Jobs
# Asynchronously send an email to a user
class UserEmail < Jobs::Base
def execute(args)
notification, post = nil
2013-02-05 14:16:51 -05:00
raise Discourse::InvalidParameters.new(:user_id) unless args[:user_id].present?
raise Discourse::InvalidParameters.new(:type) unless args[:type].present?
2013-02-05 14:16:51 -05:00
type = args[:type]
2013-02-05 14:16:51 -05:00
user = User.find_by(id: args[:user_id])
2015-11-06 13:19:13 -05:00
set_skip_context(type, args[:user_id], args[:to_address].presence || user.try(:email).presence || "no_email_found")
return skip(I18n.t("email_log.no_user", user_id: args[:user_id])) unless user
2013-02-25 11:42:20 -05:00
2013-02-05 14:16:51 -05:00
if args[:post_id]
post = Post.find_by(id: args[:post_id])
return skip(I18n.t('email_log.post_not_found', post_id: args[:post_id])) unless post.present?
end
2013-02-05 14:16:51 -05:00
if args[:notification_id].present?
notification = Notification.find_by(id: args[:notification_id])
end
message, skip_reason = message_for_email( user,
post,
type,
notification,
args[:notification_type],
args[:notification_data_hash],
args[:email_token],
args[:to_address] )
if message
Email::Sender.new(message, args[:type], user).send
else
skip_reason
2013-02-05 14:16:51 -05:00
end
end
def set_skip_context(type, user_id, to_address)
@skip_context = { type: type, user_id: user_id, to_address: to_address }
end
NOTIFICATIONS_SENT_BY_MAILING_LIST ||= Set.new [
Notification.types[:posted],
Notification.types[:replied],
Notification.types[:mentioned],
Notification.types[:group_mentioned],
Notification.types[:quoted],
]
def message_for_email(user, post, type, notification,
notification_type=nil, notification_data_hash=nil,
email_token=nil, to_address=nil)
set_skip_context(type, user.id, to_address || user.email)
2013-02-05 14:16:51 -05:00
return skip_message(I18n.t("email_log.anonymous_user")) if user.anonymous?
return skip_message(I18n.t("email_log.suspended_not_pm")) if user.suspended? && type != :user_private_message
2013-02-05 14:16:51 -05:00
return if user.staged && type == :digest
2013-02-25 11:42:20 -05:00
seen_recently = (user.last_seen_at.present? && user.last_seen_at > SiteSetting.email_time_window_mins.minutes.ago)
seen_recently = false if user.email_always || user.staged
2013-02-05 14:16:51 -05:00
email_args = {}
if post || notification || notification_type
return skip_message(I18n.t('email_log.seen_recently')) if seen_recently && !user.suspended?
end
if post
email_args[:post] = post
2013-02-05 14:16:51 -05:00
end
if notification || notification_type
email_args[:notification_type] ||= notification_type || notification.try(:notification_type)
email_args[:notification_data_hash] ||= notification_data_hash || notification.try(:data_hash)
if user.mailing_list_mode? &&
!post.topic.private_message? &&
NOTIFICATIONS_SENT_BY_MAILING_LIST.include?(email_args[:notification_type])
# no need to log a reason when the mail was already sent via the mailing list job
return [nil, nil]
end
unless user.email_always?
if (notification && notification.read?) || (post && post.seen?(user))
return skip_message(I18n.t('email_log.notification_already_read'))
end
end
end
skip_reason = skip_email_for_post(post, user)
return skip_message(skip_reason) if skip_reason
2013-02-05 14:16:51 -05:00
# Make sure that mailer exists
raise Discourse::InvalidParameters.new("type=#{type}") unless UserNotifications.respond_to?(type)
if email_token.present?
email_args[:email_token] = email_token
end
2013-02-25 11:42:20 -05:00
message = UserNotifications.send(type, user, email_args)
2013-02-05 14:16:51 -05:00
# Update the to address if we have a custom one
if message && to_address.present?
message.to = [to_address]
2013-02-05 14:16:51 -05:00
end
[message, nil]
end
private
2013-02-05 14:16:51 -05:00
def skip_message(reason)
[nil, skip(reason)]
end
# If this email has a related post, don't send an email if it's been deleted or seen recently.
def skip_email_for_post(post, user)
if post
return I18n.t('email_log.topic_nil') if post.topic.blank?
return I18n.t('email_log.post_deleted') if post.user_deleted?
return I18n.t('email_log.user_suspended') if (user.suspended? && !post.user.try(:staff?))
return I18n.t('email_log.already_read') if PostTiming.where(topic_id: post.topic_id, post_number: post.post_number, user_id: user.id).present?
else
false
end
end
def skip(reason)
EmailLog.create!(
email_type: @skip_context[:type],
to_address: @skip_context[:to_address],
user_id: @skip_context[:user_id],
skipped: true,
skipped_reason: reason,
)
2013-02-05 14:16:51 -05:00
end
end
end