discourse/app/jobs/scheduled/poll_mailbox.rb

101 lines
3.6 KiB
Ruby
Raw Normal View History

#
# Connects to a mailbox and checks for replies
#
require 'net/pop'
require_dependency 'email/receiver'
require_dependency 'email/sender'
require_dependency 'email/message_builder'
module Jobs
2013-08-08 01:25:05 +08:00
class PollMailbox < Jobs::Scheduled
every SiteSetting.pop3_polling_period_mins.minutes
sidekiq_options retry: false
include Email::BuildEmailHelper
def execute(args)
@args = args
poll_pop3 if SiteSetting.pop3_polling_enabled?
end
def handle_mail(mail)
begin
mail_string = mail.pop
Email::Receiver.new(mail_string).process
rescue => e
handle_failure(mail_string, e)
ensure
mail.delete
end
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 = {}
case e
when Email::Receiver::UserNotSufficientTrustLevelError
message_template = :email_reject_trust_level
when Email::Receiver::UserNotFoundError
message_template = :email_reject_no_account
when Email::Receiver::EmptyEmailError
message_template = :email_reject_empty
when Email::Receiver::EmailUnparsableError
message_template = :email_reject_parsing
when Email::Receiver::EmailLogNotFound
message_template = :email_reject_reply_key
2014-08-14 02:47:21 +08:00
when Email::Receiver::BadDestinationAddress
message_template = :email_reject_destination
when Email::Receiver::TopicNotFoundError
message_template = :email_reject_topic_not_found
when Email::Receiver::TopicClosedError
message_template = :email_reject_topic_closed
when Email::Receiver::AutoGeneratedEmailError
message_template = :email_reject_auto_generated
when Discourse::InvalidAccess
message_template = :email_reject_invalid_access
when ActiveRecord::Rollback
message_template = :email_reject_post_error
when Email::Receiver::InvalidPost
if e.message.length < 6
message_template = :email_reject_post_error
else
message_template = :email_reject_post_error_specified
template_args[:post_error] = e.message
end
else
message_template = nil
end
if message_template
# inform the user about the rejection
message = Mail::Message.new(mail_string)
template_args[:former_title] = message.subject
template_args[:destination] = message.to
template_args[:site_name] = SiteSetting.title
client_message = RejectionMailer.send_rejection(message_template, message.from, template_args)
Email::Sender.new(client_message, message_template).send
else
Discourse.handle_job_exception(e, error_context(@args, "Unrecognized error type when processing incoming email", mail: mail_string))
end
end
def poll_pop3
connection = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port)
connection.enable_ssl if SiteSetting.pop3_polling_ssl
connection.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
unless pop.mails.empty?
pop.each { |mail| handle_mail(mail) }
end
2014-04-15 04:55:57 +08:00
pop.finish
end
2014-04-10 01:26:19 +08:00
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
end