標籤:ruby mailfactory openssl mail 發送郵件
其實只要你任性的可以,用telnet也是可以發郵件的哦。不過本貓沒那麼任性,還是用KISS原則來發郵件吧。本篇博文只介紹了如何發郵件,但沒涉及收郵件的事,以後如有機會會單獨開一篇博文介紹。
ruby通過smtp發郵件有2種操作手段,一是直接用Net::SMTP來發送,比較底層。如果還要發送附件,則需要額外gem:mailfactory,而mailfactory又依賴於包mime-types。即便如此如果郵件伺服器串連需要ssl,則還需要require檔案smtp-tls.rb,而這個rb檔案需要openssl包的支援啊!第二種方法是直接使用高層的gem包mail,包含添加附件的功能,不過該gem也依賴於mime-types包,這個包專門用來描述郵件檔案格式的,俗稱多用途互連網郵件擴充類型啊。下面依次介紹下每種方法。
方法一:使用Net::SMTP
正常的非加密串連的smtp連接埠號碼為25,如果是加密則可能為587或465,要看具體的郵件伺服器的說明。開始用的是QQ的郵件伺服器,但老是不穩定,遂換為hotmail的,但hotmail需要ssl串連。按上面所述需要openssl包。麻煩開始了:rubygems.org用gem死活連不上,後來將openssl.gem直接下載到本地,用gem install -l openssl.gem安裝,發現require還是出錯,需要native ext:openssl.so動態庫擴充,進入openssl的ext原始碼目錄用make編譯提示出錯:Ignore OpenSSL broken by Apple,提示我用其他的openssl庫路徑,我用毛啊!是不支援Mac OS X嗎?但是檢查了系統中是安裝過openssl的:
/private/etc/openssl
/private/etc/openssl/cert.pem
/usr/bin/openssl
/usr/lib/pkgconfig/openssl.pc
/usr/local/Cellar/openssl
動態庫也是存在的,但不是ruby 的c_ext!
[email protected]: ruby_src$locate libssl.dylib
/Applications/Xcode6-Beta4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libssl.dylib
/Applications/Xcode6-Beta4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib/libssl.dylib
/opt/com.bitaxis/lib/libssl.dylib
/opt/local/lib/libssl.dylib
/usr/lib/libssl.dylib
/usr/local/Cellar/openssl/1.0.1e/lib/libssl.dylib
神馬情況?考慮到tk對ruby的問題(見我另一篇在mac OS X下ruby使用tk的博文),我懷疑該ruby版本本身不支援原生openssl,這個版本是我在ruby-lang下載的ruby-2.1.5原始碼編譯並且安裝的!遂用rvm下載了其ruby-2.1.5版本,一試竟然可以鳥!但隨後發現hotmail.com的加密串連還是連不上,又換回QQ郵箱,用非加密的smtp,25連接埠串連。這回基本可以穩定發送了,如果換位163的郵箱測試發現更加穩定,上未重構的代碼:
#!/usr/bin/ruby#encoding:utf-8require 'net/smtp'require './smtp-tls.rb'require 'mailfactory'#Senders and Recipientsfrom_name = 'localhost'from_mail = '[email protected]'to_name = 'ks'to_mail = '[email protected]'#Servers and Authentication#smtp_host = 'smtp.qq.com'smtp_host = 'smtp.163.com'smtp_port = 25 #465 587 25#smtp_domain = 'qq.com'smtp_domain = 'localhost.localdomain'smtp_user = "[email protected]"smtp_pwd = "xxxxxxxx"#smtp_user = "[email protected]"#smtp_pwd = 'xxxxxxxx'#The subject and the messaget = Time.nowsubj = '1331 thinkpad test hopy'msg_body = "send msg from ruby.\n"#The date/time should look something like: Thu, 03 Jan 2006 12:33:22 -0700msg_date = t.strftime("%a, %d %b %Y %H:%M:%S +0800")#Compose the message for the email
#如果使用mailfactory發送則實際用不著msg格式了msg = <<END_OF_MESSAGEDate: #{msg_date}From: #{from_name} <#{from_mail}>To: #{to_name} <#{to_mail}>Subject: #{subj}#{msg_body} END_OF_MESSAGEmail = MailFactory.newmail.to = to_mailmail.from = from_mailmail.subject = subjmail.text = msg_bodymail.attach(File.expand_path("./mail.rb")) #發送附件#smtp = Net::SMTP.new(smtp_host,587)#smtp.enable_starttls#Net::SMTP.start(smtp_host, smtp_port, smtp_domain, smtp_user, smtp_pwd, :plain) do |smtp|Net::SMTP.start(smtp_host,smtp_port,smtp_domain, smtp_user, smtp_pwd, :login) do |smtp| #smtp.send_message msg, smtp_user, to_mail #mail.to = to_mail #puts smtp.methods #smtp.enable_starttls smtp.send_message(mail.to_s,smtp_user,to_mail)end
方法二:使用ruby gem:mail(未完待續)
ruby用來發送互連網郵件