メールは、電子メールの生成、解析、シンプルでRubyesqueの送信を処理するように設計されたRuby用のインターネットライブラリです。
このライブラリの目的は、電子メールの送信や受信など、すべての電子メール関数を処理するための単一のアクセスポイントを提供することです。すべてのネットワークタイプのアクションは、プロキシメソッドを通じてNET :: SMTP、Net :: POP3などを通じて行われます。
Tmailでの私の経験から構築されたこのように、電子メールを生成、送信、解析することを簡単にする純粋なRubyの実装として設計されています。
また、より近代的なバージョンのRubyで動作するようにゼロから設計されています。 Modern Rubiesは以前よりもはるかに素晴らしくテキストのエンコーディングを処理するため、これらの機能はこのライブラリで最大限に活用されており、メールはTmailよりも多くのメッセージをよりきれいに処理できます。
最後に、メールは非常にシンプルなオブジェクト指向システムを使用して設計されており、実際に解析している電子メールメッセージを開きます。自分が何をしているのか知っている場合、メールの最後のビットごとに直接いじることができます。
はい、あなた!メールは、世界中の人々が数え切れないほどのアプリで使用しています。それは、すべてのオープンソースソフトウェアと同様に、私たちの自由時間から生まれた愛の労働です。感謝したい場合は、私たちと一緒に掘り下げて貢献してください!トリアージとGitHubの問題を修正し、ドキュメントを改善し、新しい機能を追加します。ピッチングありがとうございます。
メールはテストされています:
Rubyの新しいバージョンがリリースされると、Mailは「プレビュー」とすべての「通常のメンテナンス」、「セキュリティメンテナンス」、およびRubyメンテナンスブランチページにリストされている2つの最新の「終末」バージョンのサポートと互換性があります。新しいプレビューリリースのサポートを追加するのを支援するためのリクエストをプルすることは大歓迎です。
すべてのメールコミットは、すべてのサポートされているRubyバージョンのGitHubアクションによってテストされます。
気になった個人とメールについて話し合いたい場合は、Googleグループに登録してください。
メールはRFC5322とRFC6532に準拠しています。つまり、US-ASCIIおよびUTF-8の電子メールを解析してUS-ASCIIメールを生成できます。問題が発生する廃止された電子メールの構文がいくつかありますが、それは非常に堅牢です。つまり、それがクラッシュしないことを理解していないものを見つけた場合、代わりに問題をスキップして解析し続けることを意味します。理解できないヘッダーの場合、ヘッダーをオプションの非構造化フィールドとして初期化し、解析を続けます。
これは、メールがデータを(これまで)クランチしないことを意味します(私は思う)。
マイムメールを作成することもできます。テキスト/プレーンとテキスト/HTML(最も一般的なペア)のマルチパート/代替メールを作成するためのヘルパー方法があり、他のタイプのMIMEメールを手動で作成できます。
次のdodo:
基本的に...私たちは郵便でbddを行います。対応またはカバーする仕様なしで、メソッドが郵送されることはありません。 RCOVで測定される最低100%のカバレッジとして期待されています。これはどんな尺度でも完璧ではありませんが、かなり良いです。さらに、Tmailからのすべての機能テストは、宝石がリリースされる前に通過します。
また、メールが正しく動作することを確認できることを意味します。
bundle exec rspec
を実行して、テストをローカルに実行できます。
ACTを使用して、サポートされているすべてのRubyバージョンでテストを実行できます。
単一のポイントリリース内にAPI削除はありません。除去前に少なくとも1つのマイナーなポイントリリースのために、警告で廃止されるすべての除去。
また、そのように宣言されるすべてのプライベートまたは保護された方法 - これはまだi/pです。
インストールはかなり簡単です。私はRubygemsでメールをホストしているので、あなたはただすることができます:
# gem install mail
知らなかった場合、メールでエンコーディングを処理することは、期待するほど簡単ではありません。
私はそれを単純化しようとしました:
電子メールにレンダリングできるすべてのオブジェクトは、 #encoded
メソッドを持っています。エンコードされたエンコードは、メールシステムで送信する準備ができた完全な文字列としてオブジェクトを返します。つまり、ヘッダーフィールドと値とCRLFが最後に含まれ、必要に応じてラップされます。
電子メールにレンダリングできるすべてのオブジェクトは、 #decoded
メソッドを持っています。デコードされたものは、オブジェクトの「値」を文字列としてのみ返します。これは、ヘッダーフィールドが含まれないことを意味します( 'to'または 'subject:'など)。
デフォルトでは、コンテナオブジェクトで#to_s
呼び出すとエンコードされたメソッドを呼び出し、フィールドオブジェクトの#to_s
デコードされたメソッドを呼び出します。したがって、メールオブジェクトで#to_s
#to_s
とメールが返され、すべてエンコードされたすべてのエンコードが送信されます。メールのヘッダーオブジェクトはコンテナと見なされます。疑わしい場合は、 #encoded
を呼び出すか、 #decoded
明示的にコードしている場合は、わからない場合は安全です。
エンコードできるパラメーター値(コンテンツタイプなど)を持つ構造化されたフィールドは、オブジェクトに対するメソッドとしてパラメーター名を呼び出すと、デコードされたパラメーター値を提供します。
object.parameters['<parameter_name>']
メソッドコールを介してパラメーター名を呼び出すと、エンコードできるパラメーター値(コンテンツタイプなど)を持つ構造化されたフィールドは、エンコードされたパラメーター値を提供します。
してください!貢献は簡単です。詳細については、Convinting.MDドキュメントをお読みください。
すべての主要なメール関数は、メールモジュールから発生することができるはずです。したがって、開始するにはrequire 'mail'
だけです。
mail
Rubyコードで非常によく文書化されています。 rubydoc.infoで調べることができます。
mail = Mail . new do
from '[email protected]'
to '[email protected]'
subject 'This is a test email'
body File . read ( 'body.txt' )
end
mail . to_s #=> "From: [email protected]: you@...
mail = Mail . new do
body File . read ( 'body.txt' )
end
mail [ 'from' ] = '[email protected]'
mail [ :to ] = '[email protected]'
mail . subject = 'This is a test email'
mail . header [ 'X-Custom-Header' ] = 'custom value'
mail . to_s #=> "From: [email protected]: you@...
mail = Mail . new do
to '[email protected]'
body 'Some simple body'
end
mail . to_s =~ /Message - ID: <[ d w _]+@.+.mail/ #=> 27
メールは、メッセージが欠落している場合にメッセージ-IDフィールドを自動的に追加し、次の行に沿って一意のランダムなメッセージIDを提供します。
mail = Mail . new do
to '[email protected]'
message_id '<[email protected]>'
body 'Some simple body'
end
mail . to_s =~ /Message - ID: <[email protected]>/ #=> 27
メールは、あなたが何をしているのかを知っていると信頼して、あなたがそれに割り当てるメッセージを受け取ります。
SMTP経由でローカルホストポートへの送信にデフォルトで送信します。このポートでsendmailまたはpostfixデーモンがある場合は、メールの送信は簡単です。
Mail . deliver do
from '[email protected]'
to '[email protected]'
subject 'Here is the image you wanted'
body File . read ( 'body.txt' )
add_file '/full/path/to/somefile.png'
end
または
mail = Mail . new do
from '[email protected]'
to '[email protected]'
subject 'Here is the image you wanted'
body File . read ( 'body.txt' )
add_file :filename => 'somefile.png' , :content => File . read ( '/somefile.png' )
end
mail . deliver!
sendmail経由で送信すると、次のように行うことができます。
mail = Mail . new do
from '[email protected]'
to '[email protected]'
subject 'Here is the image you wanted'
body File . read ( 'body.txt' )
add_file :filename => 'somefile.png' , :content => File . read ( '/somefile.png' )
end
mail . delivery_method :sendmail
mail . deliver
SMTP経由で送信(たとえばMailCatcherに)
Mail . defaults do
delivery_method :smtp , address : "localhost" , port : 1025
end
Eximは独自の配達マネージャーを必要とし、次のように使用できます。
mail . delivery_method :exim , :location => "/usr/bin/exim"
mail . deliver
郵便物は、開発とテストのために、ログファイルにも「配信」される場合があります。
# Delivers by logging the encoded message to $stdout
mail . delivery_method :logger
# Delivers to an existing logger at :debug severity
mail . delivery_method :logger , logger : other_logger , severity : :debug
メールをMail.defaults
内でretriever_method
使用してメールを受信するためにメールを構成できます。
# e.g. POP3
Mail . defaults do
retriever_method :pop3 , :address => "pop.gmail.com" ,
:port => 995 ,
:user_name => '<username>' ,
:password => '<password>' ,
:enable_ssl => true
end
# IMAP
Mail . defaults do
retriever_method :imap , :address => "imap.mailbox.org" ,
:port => 993 ,
:user_name => '<username>' ,
:password => '<password>' ,
:enable_ssl => true
end
受信メールにさまざまな方法でアクセスできます。
最新のメール:
Mail . all #=> Returns an array of all emails
Mail . first #=> Returns the first unread email
Mail . last #=> Returns the last unread email
昇順で日付でソートされた最初の10メール:
emails = Mail . find ( :what => :first , :count => 10 , :order => :asc )
emails . length #=> 10
またはすべてのメールでさえ:
emails = Mail . all
emails . length #=> LOTS!
mail = Mail . read ( '/path/to/message.eml' )
mail . envelope_from #=> '[email protected]'
mail . from . addresses #=> ['[email protected]', '[email protected]']
mail . sender . address #=> '[email protected]'
mail . to #=> '[email protected]'
mail . cc #=> '[email protected]'
mail . subject #=> "This is the subject"
mail . date . to_s #=> '21 Nov 1997 09:55:06 -0600'
mail . message_id #=> '<[email protected]>'
mail . decoded #=> 'This is the body of the email...
さらに多くの方法が利用可能です。
mail = Mail . read ( 'multipart_email' )
mail . multipart? #=> true
mail . parts . length #=> 2
mail . body . preamble #=> "Text before the first part"
mail . body . epilogue #=> "Text after the last part"
mail . parts . map { | p | p . content_type } #=> ['text/plain', 'application/pdf']
mail . parts . map { | p | p . class } #=> [Mail::Message, Mail::Message]
mail . parts [ 0 ] . content_type_parameters #=> {'charset' => 'ISO-8859-1'}
mail . parts [ 1 ] . content_type_parameters #=> {'name' => 'my.pdf'}
メールパーツの木を生成します。それぞれのメッセージには、多くの部品があります。各部分は、部品が多いか、またはまったくないことができる別のメッセージです。
メッセージには、マルチパート/混合またはマルチパート/関連コンテンツタイプであり、境界が定義されている場合にのみパーツがあります。
mail . attachments . each do | attachment |
# Attachments is an AttachmentsList object containing a
# number of Part objects
if ( attachment . content_type . start_with? ( 'image/' ) )
# extracting images for example...
filename = attachment . filename
begin
File . open ( images_dir + filename , "w+b" , 0644 ) { | f | f . write attachment . decoded }
rescue => e
puts "Unable to save data for #{ filename } because #{ e . message } "
end
end
end
メールはいくつかの基本的な仮定を行い、可能な限り共通のことを行うことを可能にします....(メールライブラリから多くを求めています)
mail = Mail . deliver do
part :content_type => "multipart/mixed" do | p1 |
p1 . part :content_type => "multipart/related" do | p2 |
p2 . part :content_type => "multipart/alternative" ,
:content_disposition => "inline" do | p3 |
p3 . part :content_type => "text/plain; charset=utf-8" ,
:body => "Here is the attachment you wanted n "
p3 . part :content_type => "text/html; charset=utf-8" ,
:body => "<h1>Funky Title</h1><p>Here is the attachment you wanted</p> n "
end
end
add_file '/path/to/myfile.pdf'
end
from "Mikel Lindsaar <[email protected]>"
to "[email protected]"
subject "First multipart email sent with Mail"
end
その後、メールはブロックの最後にメールを配信し、結果のメール::メッセージオブジェクトを返します。その後、必要に応じて検査できます...
puts mail.to_s #=>
Date: Tue, 26 Apr 2022 20:12:07 +0200
From: Mikel Lindsaar <[email protected]>
To: [email protected]
Message-ID: <[email protected]>
Subject: First multipart email sent with Mail
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="--==_mimepart_626835f733867_10873fdfa3c2ffd494636";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_626835f733867_10873fdfa3c2ffd494636
Content-Type: multipart/mixed;
boundary="--==_mimepart_626835f73382a_10873fdfa3c2ffd494518";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_626835f73382a_10873fdfa3c2ffd494518
Content-Type: multipart/related;
boundary="--==_mimepart_626835f7337f5_10873fdfa3c2ffd494438";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_626835f7337f5_10873fdfa3c2ffd494438
Content-Type: multipart/alternative;
boundary="--==_mimepart_626835f733702_10873fdfa3c2ffd494376";
charset=UTF-8
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Content-ID: <[email protected]>
----==_mimepart_626835f733702_10873fdfa3c2ffd494376
Content-Type: text/plain;
charset=utf-8
Content-Transfer-Encoding: 7bit
Here is the attachment you wanted
----==_mimepart_626835f733702_10873fdfa3c2ffd494376
Content-Type: text/html;
charset=utf-8
Content-Transfer-Encoding: 7bit
<h1>Funky Title</h1><p>Here is the attachment you wanted</p>
----==_mimepart_626835f733702_10873fdfa3c2ffd494376--
----==_mimepart_626835f7337f5_10873fdfa3c2ffd494438--
----==_mimepart_626835f73382a_10873fdfa3c2ffd494518--
----==_mimepart_626835f733867_10873fdfa3c2ffd494636
Content-Type: text/plain;
charset=UTF-8;
filename=myfile.txt
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=myfile.txt
Content-ID: <6
[email protected]>
Hallo,
Test
End
----==_mimepart_626835f733867_10873fdfa3c2ffd494636--
メールは、コンテンツ転送エンコード、MIMEバージョン、コンテンツIDを挿入し、コンテンツタイプと境界を処理します。
メールは、体内のテキストが私たちのみである場合、転送エンコードは7ビットで、テキスト/プレーンであると想定しています。これを明示的に宣言することでこれをオーバーライドできます。
テキストとHTMLパーツを含むブロックを使用する必要はありません。宣言的に行うことができます。ただし、メールではなく、メール::メールにメール:: Partsを追加する必要があります。
mail = Mail . new do
to '[email protected]'
from 'Mikel Lindsaar <[email protected]>'
subject 'First multipart email sent with Mail'
end
text_part = Mail :: Part . new do
body 'This is plain text'
end
html_part = Mail :: Part . new do
content_type 'text/html; charset=UTF-8'
body '<h1>This is HTML</h1>'
end
mail . text_part = text_part
mail . html_part = html_part
ブロックフォームを使用して完了したのと同じ電子メールが表示されます
@mail = Mail . read ( '/path/to/bounce_message.eml' )
@mail . bounced? #=> true
@mail . final_recipient #=> rfc822;[email protected]
@mail . action #=> failed
@mail . error_status #=> 5.5.0
@mail . diagnostic_code #=> smtp;550 Requested action not taken: mailbox unavailable
@mail . retryable? #=> false
絶対パスからファイルを読み取るだけで、メールはmime_typeを推測しようとし、base64でファイルをエンコードします。
@mail = Mail . new
@mail . add_file ( "/path/to/file.jpg" )
@mail . parts . first . attachment? #=> true
@mail . parts . first . content_transfer_encoding . to_s #=> 'base64'
@mail . attachments . first . mime_type #=> 'image/jpg'
@mail . attachments . first . filename #=> 'file.jpg'
@mail . attachments . first . decoded == File . read ( '/path/to/file.jpg' ) #=> true
または、file_dataを渡してファイル名を付けることができます。もう一度、メールはmime_typeを推測して推測します。
@mail = Mail . new
@mail . attachments [ 'myfile.pdf' ] = File . read ( 'path/to/myfile.pdf' )
@mail . parts . first . attachment? #=> true
@mail . attachments . first . mime_type #=> 'application/pdf'
@mail . attachments . first . decoded == File . read ( 'path/to/myfile.pdf' ) #=> true
また、メールよりもよく知っている場合、推測されたMimeメディアタイプをオーバーライドすることもできます(これはめったに必要ありません)
@mail = Mail . new
@mail . attachments [ 'myfile.pdf' ] = { :mime_type => 'application/x-pdf' ,
:content => File . read ( 'path/to/myfile.pdf' ) }
@mail . parts . first . mime_type #=> 'application/x-pdf'
もちろん...メールも添付ファイルを往復します
@mail = Mail . new do
to '[email protected]'
from 'Mikel Lindsaar <[email protected]>'
subject 'First multipart email sent with Mail'
text_part do
body 'Here is the attachment you wanted'
end
html_part do
content_type 'text/html; charset=UTF-8'
body '<h1>Funky Title</h1><p>Here is the attachment you wanted</p>'
end
add_file '/path/to/myfile.pdf'
end
@round_tripped_mail = Mail . new ( @mail . encoded )
@round_tripped_mail . attachments . length #=> 1
@round_tripped_mail . attachments . first . filename #=> 'myfile.pdf'
詳細については、上記の「添付ファイルのテストと抽出」を参照してください。
メールがシステムの一部である場合、実際に電子メールを送信せずにテストする方法が必要です。TestMailerはこれを実行できます。
require 'mail'
=> true
Mail . defaults do
delivery_method :test
end
=> #<Mail::Configuration:0x19345a8 @delivery_method=Mail::TestMailer>
Mail :: TestMailer . deliveries
=> [ ]
Mail . deliver do
to '[email protected]'
from '[email protected]'
subject 'testing'
body 'hello'
end
=> #<Mail::Message:0x19284ec ...
Mail :: TestMailer . deliveries . length
=> 1
Mail :: TestMailer . deliveries . first
=> #<Mail::Message:0x19284ec ...
Mail :: TestMailer . deliveries . clear
=> [ ]
また、shouldaのActionMailer Matchersに盗まれた/インスピレーションを受けたrspecマッチャーのセットもあります(上記のようにdelivery_method
設定する必要があります):
Mail . defaults do
delivery_method :test # in practice you'd do this in spec_helper.rb
end
RSpec . describe "sending an email" do
include Mail :: Matchers
before ( :each ) do
Mail :: TestMailer . deliveries . clear
Mail . deliver do
to [ '[email protected]' , '[email protected]' ]
from '[email protected]'
subject 'testing'
body 'hello'
end
end
it { is_expected . to have_sent_email } # passes if any email at all was sent
it { is_expected . to have_sent_email . from ( '[email protected]' ) }
it { is_expected . to have_sent_email . to ( '[email protected]' ) }
# can specify a list of recipients...
it { is_expected . to have_sent_email . to ( [ '[email protected]' , '[email protected]' ] ) }
# ...or chain recipients together
it { is_expected . to have_sent_email . to ( '[email protected]' ) . to ( '[email protected]' ) }
it { is_expected . to have_sent_email . with_subject ( 'testing' ) }
it { is_expected . to have_sent_email . with_body ( 'hello' ) }
# Can match subject or body with a regex
# (or anything that responds_to? :match)
it { is_expected . to have_sent_email . matching_subject ( /test(ing)?/ ) }
it { is_expected . to have_sent_email . matching_body ( /h(a|e)llo/ ) }
# Can chain together modifiers
# Note that apart from recipients, repeating a modifier overwrites old value.
it { is_expected . to have_sent_email . from ( '[email protected]' ) . to ( '[email protected]' ) . matching_body ( /hell/ )
# test for attachments
# ... by specific attachment
it { is_expected . to have_sent_email . with_attachments ( my_attachment ) }
# ... or any attachment
it { is_expected . to have_sent_email . with_attachments ( any_attachment ) }
# ... or attachment with filename
it { is_expected . to have_sent_email . with_attachments ( an_attachment_with_filename ( 'file.txt' ) ) }
# ... or attachment with mime_type
it { is_expected . to have_sent_email . with_attachments ( an_attachment_with_mime_type ( 'application/pdf' ) ) }
# ... by array of attachments
it { is_expected . to have_sent_email . with_attachments ( [ my_attachment1 , my_attachment2 ] ) } #note that order is important
#... by presence
it { is_expected . to have_sent_email . with_any_attachments }
#... or by absence
it { is_expected . to have_sent_email . with_no_attachments }
end
スペック/フィクスチャー/電子メール/from_trec_2005の仕様ファイルは、2005年のTRECパブリックスパムコーパスからのものです。それらは、そのプロジェクトとライセンス契約の条件の下で著作権を保護したままです。このプロジェクトでは、この電子メールパーサーの実装の開発を検証および説明するために使用されます。
http://plg.uwaterloo.ca/~gvcormac/treccorpus/
それらは、「許可された使用、条項3」によって許可されているように使用されます。
"Small excerpts of the information may be displayed to others
or published in a scientific or technical context, solely for
the purpose of describing the research and development and
related issues."
-- http://plg.uwaterloo.ca/~gvcormac/treccorpus/
(MITライセンス)
Copyright(c)2009-2016 Mikel Lindsaar
このソフトウェアおよび関連するドキュメントファイル(「ソフトウェア」)のコピーを取得している人に、これにより許可が無料で許可されます。 、ソフトウェアのコピーを公開、配布、サブライセンス、および/または販売し、次の条件を条件として、ソフトウェアが提供される人を許可します。
上記の著作権通知とこの許可通知は、ソフトウェアのすべてのコピーまたはかなりの部分に含まれるものとします。
このソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むがこれらに限定されない、明示的または黙示的ないかなる種類の保証なしに「現状のまま」提供されます。いかなる場合でも、著者または著作権所有者は、契約、不法行為、またはその他の訴訟、ソフトウェアまたは使用またはその他の取引に関連する、またはその他の契約、またはその他の請求、またはその他の責任について責任を負いません。ソフトウェア。