# encoding: utf-8 module Mail # Allows you to create a new Mail::Message object. # # You can make an email via passing a string or passing a block. # # For example, the following two examples will create the same email # message: # # Creating via a string: # # string = "To: mikel@test.lindsaar.net\r\n" # string << "From: bob@test.lindsaar.net\r\n" # string << "Subject: This is an email\r\n" # string << "\r\n" # string << "This is the body" # Mail.new(string) # # Or creating via a block: # # message = Mail.new do # to 'mikel@test.lindsaar.net' # from 'bob@test.lindsaar.net' # subject 'This is an email' # body 'This is the body' # end # # Or creating via a hash (or hash like object): # # message = Mail.new({:to => 'mikel@test.lindsaar.net', # 'from' => 'bob@test.lindsaar.net', # :subject => 'This is an email', # :body => 'This is the body' }) # # Note, the hash keys can be strings or symbols, the passed in object # does not need to be a hash, it just needs to respond to :each_pair # and yield each key value pair. # # As a side note, you can also create a new email through creating # a Mail::Message object directly and then passing in values via string, # symbol or direct method calls. See Mail::Message for more information. # # mail = Mail.new # mail.to = 'mikel@test.lindsaar.net' # mail[:from] = 'bob@test.lindsaar.net' # mail['subject'] = 'This is an email' # mail.body = 'This is the body' def self.new(*args, &block) Message.new(args, &block) end # Sets the default delivery method and retriever method for all new Mail objects. # The delivery_method and retriever_method default to :smtp and :pop3, with defaults # set. # # So sending a new email, if you have an SMTP server running on localhost is # as easy as: # # Mail.deliver do # to 'mikel@test.lindsaar.net' # from 'bob@test.lindsaar.net' # subject 'hi there!' # body 'this is a body' # end # # If you do not specify anything, you will get the following equivalent code set in # every new mail object: # # Mail.defaults do # delivery_method :smtp, { :address => "localhost", # :port => 25, # :domain => 'localhost.localdomain', # :user_name => nil, # :password => nil, # :authentication => nil, # :enable_starttls_auto => true } # # retriever_method :pop3, { :address => "localhost", # :port => 995, # :user_name => nil, # :password => nil, # :enable_ssl => true } # end # # Mail.delivery_method.new #=> Mail::SMTP instance # Mail.retriever_method.new #=> Mail::POP3 instance # # Each mail object inherits the default set in Mail.delivery_method, however, on # a per email basis, you can override the method: # # mail.delivery_method :sendmail # # Or you can override the method and pass in settings: # # mail.delivery_method :sendmail, { :address => 'some.host' } # # You can also just modify the settings: # # mail.delivery_settings = { :address => 'some.host' } # # The passed in hash is just merged against the defaults with +merge!+ and the result # assigned the mail object. So the above example will change only the :address value # of the global smtp_settings to be 'some.host', keeping all other values def self.defaults(&block) Configuration.instance.instance_eval(&block) end # Returns the delivery method selected, defaults to an instance of Mail::SMTP def self.delivery_method Configuration.instance.delivery_method end # Returns the retriever method selected, defaults to an instance of Mail::POP3 def self.retriever_method Configuration.instance.retriever_method end # Send an email using the default configuration. You do need to set a default # configuration first before you use self.deliver, if you don't, an appropriate # error will be raised telling you to. # # If you do not specify a delivery type, SMTP will be used. # # Mail.deliver do # to 'mikel@test.lindsaar.net' # from 'ada@test.lindsaar.net' # subject 'This is a test email' # body 'Not much to say here' # end # # You can also do: # # mail = Mail.read('email.eml') # mail.deliver! # # And your email object will be created and sent. def self.deliver(*args, &block) mail = self.new(args, &block) mail.deliver mail end # Find emails from the default retriever # See Mail::Retriever for a complete documentation. def self.find(*args, &block) retriever_method.find(*args, &block) end # Finds and then deletes retrieved emails from the default retriever # See Mail::Retriever for a complete documentation. def self.find_and_delete(*args, &block) retriever_method.find_and_delete(*args, &block) end # Receive the first email(s) from the default retriever # See Mail::Retriever for a complete documentation. def self.first(*args, &block) retriever_method.first(*args, &block) end # Receive the first email(s) from the default retriever # See Mail::Retriever for a complete documentation. def self.last(*args, &block) retriever_method.last(*args, &block) end # Receive all emails from the default retriever # See Mail::Retriever for a complete documentation. def self.all(*args, &block) retriever_method.all(*args, &block) end # Reads in an email message from a path and instantiates it as a new Mail::Message def self.read(filename) self.new(File.open(filename, 'rb') { |f| f.read }) end # Delete all emails from the default retriever # See Mail::Retriever for a complete documentation. def self.delete_all(*args, &block) retriever_method.delete_all(*args, &block) end # Instantiates a new Mail::Message using a string def Mail.read_from_string(mail_as_string) Mail.new(mail_as_string) end def Mail.connection(&block) retriever_method.connection(&block) end # Initialize the observers and interceptors arrays @@delivery_notification_observers = [] @@delivery_interceptors = [] # You can register an object to be informed of every email that is sent through # this method. # # Your object needs to respond to a single method #delivered_email(mail) # which receives the email that is sent. def self.register_observer(observer) unless @@delivery_notification_observers.include?(observer) @@delivery_notification_observers << observer end end # You can register an object to be given every mail object that will be sent, # before it is sent. So if you want to add special headers or modify any # email that gets sent through the Mail library, you can do so. # # Your object needs to respond to a single method #delivering_email(mail) # which receives the email that is about to be sent. Make your modifications # directly to this object. def self.register_interceptor(interceptor) unless @@delivery_interceptors.include?(interceptor) @@delivery_interceptors << interceptor end end def self.inform_observers(mail) @@delivery_notification_observers.each do |observer| observer.delivered_email(mail) end end def self.inform_interceptors(mail) @@delivery_interceptors.each do |interceptor| interceptor.delivering_email(mail) end end protected def self.random_tag t = Time.now sprintf('%x%x_%x%x%d%x', t.to_i, t.tv_usec, $$, Thread.current.object_id.abs, self.uniq, rand(255)) end private def self.something_random (Thread.current.object_id * rand(255) / Time.now.to_f).to_s.slice(-3..-1).to_i end def self.uniq @@uniq += 1 end @@uniq = self.something_random end