require 'net/smtp' require 'base64' require 'kconv' require 'erb' # # This class sends E-mails, generated from message templates. # # Author:: FUJIWARA Teruyoshi # Copyright:: Copyright (c) 2010 FUJIWARA Teruyoshi # License:: Distributes under the same terms as Ruby # Date:: August 23, 2010 # Version:: 1.01 # # === Usage # The following is basic usage: # mt = MailTemplate.new(:smtp_server => 'smtp.server.com', # :smtp_port => 587, # :mail_from => 'foo@bar.com', # :user => 'foo@bar.com', # :password => 'XXXXXXX', # :auth_type => 'plain') # vars = { # "mail_to" => "foo@bar.com", # "subject" => "subject", # "date" => "August 15, 2010" # } # mt.send("/path/to/template.txt", vars, "recipient@buz.com") # # Template should be written in ERB form. # From: Foo # To: <%= vars["mail_to"] %> # Subject: <%= encode_header(vars["subject"]) %> # # This is a test mail from MailTemplate.rb. # This message is sent: <%= vars["date"] %> # # You should use 'vars' hash to describe variable element in the template. class MailTemplate # Initiazlize the class. Arguments are specified as hash (such as MailTemplate.new(:smtp_server => "smtphost.com", :smtp_port => 23, :mail_from = "test@test.com")) # === Options # [:smtp_server] SMTP server (mandatory) # [:smtp_port] SMTP port (mandatory) # [:mail_from] Sender's mail address (mandatory) # [:domain] Sender's domain. If not specified, "localhost.localdomain" is set as default value. # [:user] username for SMTP-AUTH # [:password] password SMTP-AUTH # [:auth_type] type of SMTP-AUTH # [:verbose] output verbose logging message. # === Return value # No value returned, but ArgumentError thrown if any mandatory argument isn't specified. def initialize(params) if (params[:verbose]) @verbose = true else @verbose = false end if (params[:smtp_server]) @server = params[:smtp_server] puts "SMTP server: #{@server}" if @verbose else raise(ArgumentError, "smtp_server must be specified.") end if (params[:smtp_port]) @port = params[:smtp_port] else @port = 23 end puts "SMTP port: #{@port}" if @verbose if (params[:mail_from]) @mail_from = params[:mail_from] puts "E-mail address (sender): #{@mail_from}" if @verbose else raise(ArgumentError, "mail_from must be specified.") end if (params[:domain]) @domain = params[:domain] else @domain = 'localhost.localdomain' end puts "Domain (sender): #{@domain}" if @verbose @user = params[:user] @password = params[:password] @auth_type = params[:auth_type] puts "User/Password/Auth type: #{@user}/#{@password}/#{@auth_type}" if @verbose end # Send an email with message generated from template and 'vars' hash. # === Argument # [template_file] Pathname of a template file. This template file must be written in ERB form. # [vars] A hash used to rewrite the template. # [mail_to] An e-mail address of recipient. # === Return value # No value returned. def send(template_file, vars, mail_to) mail_string = apply_template(template_file, vars) if @verbose puts("--------------------------------------------------") puts(mail_string) puts("--------------------------------------------------") print("sending...") end Net::SMTP.start(@server, @port, @domain, @user, @password, @auth_type) do |smtp| smtp.send_message(mail_string, @mail_from, mail_to) end puts("done.") if @verbose end # Generate message body using ERB. # === Arguments # [template_file] Pathname of a template file. This template file must be written in ERB form. # [vars] A hash used to rewrite the template. # === Return value # A string is returned. It has a message body genereted from a template. def apply_template(template_file, vars) f = File.open(template_file) template_str = f.read f.close erb = ERB.new(template_str) return erb.result(binding).tojis end protected :apply_template # Mime encode a string for a mail header. # === Argument # [str] a string to be encoded. # === Return value # A string encoded in B-encoding. def encode_header(str) enc = Kconv.tojis(str).split(//,1).pack('m').chomp.gsub("\n", '') return "=?ISO-2022-JP?B?#{enc}?=" end end