それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Rubyでメールを送るTMailのよくある使い方。(Return-path・添付ファイル・gmail/TLS)

Rubyでメールを送るにはTMialを使う。

Rubyでメールを送るTMailでいろいろやってみた。


TMmailはメールの統合ライブラリ。なのでサポートしている規模が大きい。

  • メールパーサー
  • MBoxパーサー
  • メール作成
  • 添付ファイル処理
  • エラーメール処理

などなど

各種機能がある。ただし、それぞれ実装されたタイミングなのか、APIに若干の設計思想の違いがあり、ちょっと戸惑うことが多い。

本家をみながら試した

TMail ユーザーマニュアル

単純送信

まずは単純なテキスト送信から
これを参考に→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つ添付されている状態と言える。

Ruby/TMail - 俺の基地

添付ファイルをつけて本文をつける。
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サーバーで送りたい

GmailSMTPでなく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クラスを作ったりするのが便利そう。