discourse/lib/tasks/emails.rake
2023-01-09 12:10:19 +00:00

210 lines
7.2 KiB
Ruby

# frozen_string_literal: true
def process_popmail(popmail)
begin
mail_string = popmail.pop
Email::Receiver.new(mail_string).process
rescue StandardError
putc "!"
else
putc "."
end
end
desc "use this task to import a mailbox into Discourse"
task "emails:import" => :environment do
begin
unless SiteSetting.email_in
puts "ERROR: you should enable the 'email_in' site setting before running this task"
exit(1)
end
address = ENV["ADDRESS"].presence || "pop.gmail.com"
port = (ENV["PORT"].presence || 995).to_i
ssl = (ENV["SSL"].presence || "1") == "1"
username = ENV["USERNAME"].presence
password = ENV["PASSWORD"].presence
if username.blank?
puts "ERROR: expecting USERNAME=<username> rake emails:import"
exit(2)
elsif password.blank?
puts "ERROR: expecting PASSWORD=<password> rake emails:import"
exit(3)
end
RateLimiter.disable
mails_left = 1
pop3 = Net::POP3.new(address, port)
pop3.enable_ssl(max_version: OpenSSL::SSL::TLS1_2_VERSION) if ssl
while mails_left > 0
pop3.start(username, password) do |pop|
pop.delete_all { |p| process_popmail(p) }
mails_left = pop.n_mails
end
end
puts "Done"
rescue Net::POPAuthenticationError
puts "AUTH EXCEPTION: please make sure your credentials are correct."
exit(10)
ensure
RateLimiter.enable
end
end
desc "Check if SMTP connection is successful and send test message"
task "emails:test", [:email] => [:environment] do |_, args|
email = args[:email]
message = "OK"
begin
smtp = Discourse::Application.config.action_mailer.smtp_settings
puts <<~TEXT if smtp[:address].match(/smtp\.gmail\.com/)
#{smtp}
============================== WARNING ==============================
Sending mail with Gmail is a violation of their terms of service.
Sending with G Suite might work, but it is not recommended. For information see:
https://meta.discourse.org/t/discourse-aws-ec2-g-suite-troubleshooting/62931?u=pfaffman
========================= CONTINUING TEST ============================
TEXT
puts "Testing sending to #{email} using #{smtp[:address]}:#{smtp[:port]}, username:#{smtp[:user_name]} with #{smtp[:authentication]} auth."
# We are not formatting the messages using EmailSettingsExceptionHandler here
# because we are doing custom messages in the rake task with more details.
EmailSettingsValidator.validate_smtp(
host: smtp[:address],
port: smtp[:port],
domain: smtp[:domain] || "localhost",
username: smtp[:user_name],
password: smtp[:password],
authentication: smtp[:authentication] || "plain",
)
rescue Exception => e
if e.to_s.match(/execution expired/)
message = <<~TEXT
======================================== ERROR ========================================
Connection to port #{smtp[:port]} failed.
====================================== SOLUTION =======================================
The most likely problem is that your server has outgoing SMTP traffic blocked.
If you are using a service like Mailgun or Sendgrid, try using port 2525.
=======================================================================================
TEXT
elsif e.to_s.match(/530.*STARTTLS/)
# We can't run a preliminary test with STARTTLS, we'll just try sending the test email.
message = "OK"
elsif e.to_s.match(/535/)
message = <<~TEXT
======================================== ERROR ========================================
AUTHENTICATION FAILED
#{e}
====================================== SOLUTION =======================================
The most likely problem is that your SMTP username and/or Password is incorrect.
Check them and try again.
=======================================================================================
TEXT
elsif e.to_s.match(/Connection refused/)
message = <<~TEXT
======================================== ERROR ========================================
CONNECTION REFUSED
#{e}
====================================== SOLUTION =======================================
The most likely problem is that you have chosen the wrong port or a network problem is
blocking access from the Docker container.
Check the port and your networking configuration.
=======================================================================================
TEXT
elsif e.to_s.match(/service not known/)
message = <<~TEXT
======================================== ERROR ========================================
SMTP SERVER NOT FOUND
#{e}
====================================== SOLUTION =======================================
The most likely problem is that the host name of your SMTP server is incorrect.
Check it and try again.
=======================================================================================
TEXT
else
message = <<~TEXT
======================================== ERROR ========================================
UNEXPECTED ERROR
#{e}
====================================== SOLUTION =======================================
This is not a common error. No recommended solution exists!
Please report the exact error message above to https://meta.discourse.org/
(And a solution, if you find one!)
=======================================================================================
TEXT
end
end
if message == "OK"
puts "SMTP server connection successful."
else
puts message
exit
end
begin
puts "Sending to #{email}. . . "
email_log = Email::Sender.new(TestMailer.send_test(email), :test_message).send
case email_log
when SkippedEmailLog
puts <<~TEXT
Mail was not sent.
Reason: #{email_log.reason}
TEXT
when EmailLog
puts <<~TEXT
Mail accepted by SMTP server.
Message-ID: #{email_log.message_id}
If you do not receive the message, check your SPAM folder
or test again using a service like http://www.mail-tester.com/.
If the message is not delivered it is not a problem with Discourse.
Check the SMTP server logs for the above Message ID to see why it
failed to deliver the message.
TEXT
when nil
puts <<~TEXT
Mail was not sent.
Verify the status of the `disable_emails` site setting.
TEXT
else
puts <<~TEXT
SCRIPT BUG: Got back a #{email_log.class}
#{email_log.inspect}
Mail may or may not have been sent. Check the destination mailbox.
TEXT
end
rescue => error
puts "Sending mail failed."
puts error.message
end
puts <<~TEXT if SiteSetting.disable_emails != "no"
### WARNING
The `disable_emails` site setting is currently set to #{SiteSetting.disable_emails}.
Consider changing it to 'no' before performing any further troubleshooting.
TEXT
end