From 4bde53c484d7a0c0f557842375e965da6304b8f5 Mon Sep 17 00:00:00 2001 From: bohung Date: Wed, 2 Dec 2020 00:19:58 +0800 Subject: [PATCH] Fix sent email bug. --- app/helpers/admin/epaper_helper.rb | 4 +- .../admin/e_paper_criterias/emailer.html.erb | 4 +- lib/tasks/e_paper_tasks.rake | 110 +++++++++++++++++- 3 files changed, 109 insertions(+), 9 deletions(-) diff --git a/app/helpers/admin/epaper_helper.rb b/app/helpers/admin/epaper_helper.rb index ccde8f0..0a8bfda 100644 --- a/app/helpers/admin/epaper_helper.rb +++ b/app/helpers/admin/epaper_helper.rb @@ -23,8 +23,8 @@ module Admin::EpaperHelper topics_data = Array(topics).compact papers_data << { "category_title" => (category.title rescue nil), - "category" => category, - "topics" => topics_data + "category_id" => category.id, + "topic_ids" => topics_data.map{|t| t.id} } end end diff --git a/app/views/admin/e_paper_criterias/emailer.html.erb b/app/views/admin/e_paper_criterias/emailer.html.erb index 5fa3393..46c9610 100644 --- a/app/views/admin/e_paper_criterias/emailer.html.erb +++ b/app/views/admin/e_paper_criterias/emailer.html.erb @@ -169,8 +169,8 @@
<% papers_data.each do |papers_data_hash| %> -

" style="color: #fff;text-decoration: none;"><%= papers_data_hash["category_title"] %>

- <% topics = papers_data_hash["topics"] %> +

" style="color: #fff;text-decoration: none;"><%= papers_data_hash["category_title"] %>

+ <% topics = (papers_data_hash["topic_ids"].nil? ? papers_data_hash["topics"] : EPaperTopic.where(:id.in=>papers_data_hash["topic_ids"]).to_a) %> <% topics.each do |topic| %>
" target="_blank"><%= topic.title %> diff --git a/lib/tasks/e_paper_tasks.rake b/lib/tasks/e_paper_tasks.rake index 982f048..db443b9 100644 --- a/lib/tasks/e_paper_tasks.rake +++ b/lib/tasks/e_paper_tasks.rake @@ -1,7 +1,11 @@ # desc "Explaining what the task does" namespace :epaper do task :send_email, [:paper_criteria_id, :domain, :locale] => :environment do |task,args| - paper = PaperCriteria.find(args[:paper_criteria_id]) rescue nil + require 'net/protocol' + require 'timeout' + require 'net/smtp' + require 'openssl' + paper = PaperCriteria.find(args[:paper_criteria_id]) rescue nil page = Page.where(:module => "e_paper").first.url rescue "" papers_data = Admin::EpaperHelper.get_paper_data(paper) domain = args[:domain] @@ -22,16 +26,37 @@ namespace :epaper do paper.send_failed_emails = [] Thread.new do tmp = [] + site = Site.first + @address = site['site_settings']['address'] + @port = (site['site_settings']['port'].to_i rescue 587) + @open_timeout = 30 + @read_timeout = 60 + @debug_output = nil + tls = (site['site_settings']['enable_starttls_auto'] == "1") + from_addr = site['site_settings']['service_email'] emails_valid.each_slice(mail_limit).each do |slice_emails| - email = Email.new(:mail_subject => paper.sending_title, :mail_lang => args[:locale], :template => "admin/e_paper_criterias/emailer", :template_data => {"paper_id" => paper.id, "page" => "http://" + domain + page, "siteurl" => "http://" + domain, "papers_data" => papers_data }, :mail_to => slice_emails.join(",")) + invalid_mails = verify_email(from_addr,slice_emails,tls) + deliver_emails = slice_emails - invalid_mails + email = Email.new(:mail_subject => paper.sending_title, :mail_lang => args[:locale], :template => "admin/e_paper_criterias/emailer", :template_data => {"paper_id" => paper.id, "page" => "http://" + domain + page, "siteurl" => "http://" + domain, "papers_data" => papers_data }, :mail_to => deliver_emails) begin email.save email.deliver - puts "Sending #{slice_emails.count} emails" + puts "Sending #{deliver_emails.count} emails" rescue => e - puts [slice_emails.inspect,e,e.backtrace] - tmp += slice_emails + puts [deliver_emails.inspect,e,e.backtrace] + tmp += deliver_emails end + error_flag = 0 + begin + invalid_mails.each do |invalid_mail| + email = Email.create(:mail_subject => paper.sending_title, :mail_lang => args[:locale], :template => "admin/e_paper_criterias/emailer", :template_data => {"paper_id" => paper.id, "page" => "http://" + domain + page, "siteurl" => "http://" + domain, "papers_data" => papers_data }, :mail_to => invalid_mail) + end + rescue => e + puts [e,e.backtrace] + error_flag = 1 + end + raise "There was something went wrong." if error_flag == 1 + tmp += invalid_mails end paper.update_attributes(:send_failed_emails => tmp) end @@ -40,3 +65,78 @@ namespace :epaper do end end end +def verify_email(from_addr,check_emails,tls) #true if check_email is ok + s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do + TCPSocket.open(@address, @port) + end + @socket = new_internet_message_io(tls ? tlsconnect(s) : s) + res = get_response("MAIL FROM:<#{from_addr}>") + invalid_emails = [] + check_list = [] + if check_emails.class == String + if check_emails.include?(",") + check_list = check_emails.split(",") + else + check_list << check_emails + end + else + check_list = check_emails + end + check_list.each do |check_email| + res1 = get_response("RCPT TO:<#{check_email}>") + res2 = get_response("RCPT TO:<#{check_email}>") + if !(res1.success? && res2.success?) + invalid_emails << check_email + puts [check_email,res1.message,res2.message] + end + end + s.close + invalid_emails +end +def get_response(reqline) + res = critical { + @socket.writeline reqline + recv_response() + } + return res +end +def recv_response + buf = '' + while true + line = @socket.readline + buf << line << "\n" + break unless line[3,1] == '-' # "210-PIPELINING" + end + Net::SMTP::Response.parse(buf) +end +def critical + return Net::SMTP::Response.parse('200 dummy reply code') if @error_occurred + begin + return yield() + rescue Exception + @error_occurred = true + raise + end +end +def ssl_socket(socket, context) + OpenSSL::SSL::SSLSocket.new socket, context +end +def tlsconnect(s) + verified = false + s = ssl_socket(s, @ssl_context) + s.sync_close = true + s.connect + if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE + s.post_connection_check(@address) + end + verified = true + s + ensure + s.close unless verified +end +def new_internet_message_io(s) + io = Net::InternetMessageIO.new(s) + io.read_timeout = @read_timeout + io.debug_output = @debug_output + io +end \ No newline at end of file