Last active
August 29, 2015 14:20
-
-
Save sahglie/98849cf08bd8974f4988 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/smtp' | |
require 'pp' | |
module Net | |
class SMTPMailToError < ProtoServerError | |
attr_accessor :emails | |
def initialize(emails=[]) | |
@emails = emails | |
end | |
end | |
class SMTP | |
def rcptto_list(to_addrs) | |
raise ArgumentError, 'mail destination not given' if to_addrs.empty? | |
ok_users = [] | |
unknown_users = [] | |
to_addrs.flatten.each do |addr| | |
begin | |
rcptto addr | |
rescue SMTPError => e | |
unknown_users << addr.dump | |
else | |
ok_users << addr | |
end | |
end | |
raise ArgumentError, 'No valid mail destinations were given' if ok_users.empty? | |
ret = yield | |
unless unknown_users.empty? | |
raise SMTPMailToError.new(unknown_users) | |
end | |
ret | |
end | |
end | |
end | |
class BulkEmail < ActiveRecord::Base | |
self.table_name = "incidents.bulk_emails" | |
validates :from_email, email: { allow_blank: false } | |
validates :subject, presence: { allow_blank: false } | |
validates :to_emails, presence: { allow_blank: false }, emails: {} | |
validates :body, presence: { allow_blank: false } | |
def to | |
(to_emails.try(:split, "\n") || []).map(&:strip) | |
end | |
def from | |
from_email | |
end | |
def delivered_to | |
to - rejected_emails | |
end | |
def rejected_emails | |
(rejected_to_emails.try(:split, "\n") || []).map(&:strip) | |
end | |
def save_rejected_to_emails(emails) | |
update_attributes!(rejected_to_emails: emails.join("\n")) | |
end | |
def save_and_deliver! | |
save! && deliver! | |
end | |
def deliver! | |
mailer.deliver | |
if mailer.rejected_to_emails.count > 0 | |
emails = mailer.rejected_to_emails.join("\n") | |
update_attributes!(rejected_to_emails: emails) | |
end | |
rescue Sock::Email::Mailer::Error => e | |
update_attributes!(error_msg: e.message) | |
raise ActiveRecord::ActiveRecordError, e.message | |
end | |
private | |
def mailer | |
@mailer ||= Sock::Email::Mailer.new(self) | |
end | |
end | |
module Sock | |
module Email | |
class Mailer | |
Error = Class.new(StandardError) | |
attr_accessor :bulk_email, :rejected_to_emails | |
def initialize(ar_bulk_email) | |
@bulk_email = ar_bulk_email | |
@rejected_to_emails = [] | |
end | |
def deliver | |
smtp_session.start(*smtp_params) do |smtp| | |
begin | |
smtp.send_message(message, from, to) | |
rescue Net::SMTPMailToError => e | |
@rejected_to_emails = e.emails.map { |e| eval(e) } | |
rescue StandardError => e | |
raise Error, e.message | |
end | |
end | |
end | |
def self.deliver(email) | |
instance = self.new(email) | |
instance.deliver && instance | |
end | |
private | |
def smtp_params | |
[config(:helo_domain), config(:user), config(:password), :plain] | |
end | |
def smtp_session | |
@smtp_session ||= begin | |
sess = Net::SMTP.new(config(:hostname), config(:port)) | |
sess.enable_starttls(OpenSSL::SSL::SSLContext.new(:TLSv1_2)) | |
sess | |
end | |
end | |
def config(sym) | |
Rails.application.config.smtp_email.fetch(sym) | |
end | |
def from | |
bulk_email.from | |
end | |
def to | |
[bulk_email.to] | |
end | |
def message | |
<<-MSGSTR | |
From: #{@bulk_email.from} | |
Subject: #{@bulk_email.subject} | |
Date: #{Time.now.to_s} | |
Message-Id: <#{rand(100_000)}@security.berkeley.edu> | |
#{@bulk_email.body} | |
MSGSTR | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment