Rubyでメールを送るにはTMialを使う。
Rubyでメールを送るTMailでいろいろやってみた。
TMmailはメールの統合ライブラリ。なのでサポートしている規模が大きい。
- メールパーサー
- MBoxパーサー
- メール作成
- 添付ファイル処理
- エラーメール処理
などなど
各種機能がある。ただし、それぞれ実装されたタイミングなのか、APIに若干の設計思想の違いがあり、ちょっと戸惑うことが多い。
本家をみながら試した
単純送信
まずは単純なテキスト送信から
これを参考に→Ruby/TMail - 俺の基地
require 'net/smtp' require 'tmail' require 'base64' mail = TMail::Mail.new mail.to = 'takuya@example.jp' mail.from = 'takuya@from.example.jp' mail.subject = 'Test Mail Title ' mail.date = Time.now mail.mime_version = '1.0' mail.body = 'This is test mail.' mail.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'} #送信 Net::SMTP.start("localhost","25","local","username","password","plain") do |smtp| smtp.sendmail( mail.encoded, mail.from, mail.to) end
username, password は、localhostの認証無しであればnil,nilでいい
これでOK.とりあえずここまでで、テキストメールは送れる。
添付ファイルだけを送信
つぎは添付ファイルだけを送ってみる。
このメールでは本文の代わりに添付ファイルだけをアタッチする。
このブログのを参考に→TMailで添付ファイル付きメールの送信 - みずぴー日記
require "rubygems" require 'tmail' require 'base64' mail = TMail::Mail.new ##ヘッダ mail.to = 'takuya@to.example.com' mail.from = 'takuya@from.example.com' mail.subject = 'Test mail Title' mail.date = Time.now mail.mime_version = '1.0' ##ファイルを添付 attach = TMail::Mail.new attach.body = Base64.encode64(open('/tmp/test-1.jpg').read) attach.set_content_type 'image','jpg','name'=>file attach.set_content_disposition 'attachment','filename'=>file attach.transfer_encoding = 'base64' mail.parts.push attach #puts mail.encoded #送信 Net::SMTP.start("localhost","25","local","","","plain") do |smtp| smtp.sendmail( mail.encoded, mail.from, mail.to) end
これで添付ファイルは送れる。
重要?!添付ファイルと本文を送る
なぜかTmailは本文をPartsに入れないとダメらしいので(というか改行の取り扱い?)本文もPartsに入れるとうまくいく。
Bodyにテキストをいれて添付ファイルをつくけたらbody消えた。メソッド呼び順かなと思ったら。エンコードされたデータを見てなるほどね。
添付ファイル付きのメールというのは、内部ではメールに本文の内容と、添付ファイルの内容が2つ添付されている状態と言える。
添付ファイルをつけて本文をつける。
require 'net/smtp' require 'tmail' require 'base64' #入れもの mail.to = 'takuya@example.jp' mail.from = 'takuya@from.example.jp' mail.subject = 'Test Mail Title ' mail.date = Time.now mail.mime_version = '1.0' mail.body = 'This is test mail.' mail.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'} mail.set_content_type 'multipart', 'mixed', {"boundary" => "fooooooooooooooooooobarr"} #本文 mail_body = TMail::Mail.new mail_body.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'} mail_body.body = 'これはテストですテスト' mail.parts.push(@mail_body) #本文も添付 # 添付ファイル attach = TMail::Mail.new attach.body = Base64.encode64 File.open('foo.jpg', "rb").read attach.set_content_type 'image','jpg','name'=>'foo.jpg' attach.set_content_disposition 'attachment','filename'=>'foo.jpg' attach.transfer_encoding = 'base64' # 添付 mail.parts.push(attach) #送信 Net::SMTP.start("localhost", 25 ) do |smtp| smtp.sendmail(mail.encoded, mail.from, mail.to) end
これで添付ファイルと本文を送ることができた。mail.parts.push(@mail_body) #本文も添付がポイントっぽい。
GmailなどのSMTPSサーバーで送りたい
GmailはSMTPでなくSSLレイヤ上で通信をするのでモジュールが違う
require 'tlsmail' Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE) Net::SMTP.start("smtp.gmail.com", 587, "local", @username, @password, "plain" ){|smtp| smtp.sendmail( @mail.encoded, @mail.from, @mail.to ) }
に変更になる。
Return-PATHヘッダをつける。
大量送信やバッチ送信の場合にはエラーメールを一括で受け付けるためのヘッダを付記する。
それをReturn-Pathという。ReturnPathのためにFromを偽装しなくていいのがうれしい。
ReturnPathのTmailでの使い方。
mail = TMail::Mail.new mail["Return-Path"] = “return@example.biz" mail.to = "takuya@example.biz" mail.from "from@example.biz" mail.subject= "testmail for returnpath " mail.body="test for test of return path" mail.encoded
出力結果
Return-Path: <error-handler@example.jp> From: from-autosender-@example.jp To: takuya@example.jp Subject: test for adding Return path
ReturnPathを作ると、メールのFromでなくReturnPathに指定されたアドレスにメールが届く。
総括です。
TMailはよくできている。不足機能は全くない。ただし、E-Mailの知識は必要。
アタリマエのことだけれど、それを隠すべきか隠さざるべきは、別の問題。Tmailは良く出来てる。
不要な機能は隠し、必要な機能でAPIや呼び出し順を好きな方にした、Wrapperクラスを作ったりするのが便利そう。