私は実際、ほんの数ヶ月前にこの問題に対処しました。仕事をしている製品に、送信と受信の両方でメール機能を追加しました。最初の部分はユーザーにリマインダーを送信することでしたが、顧客管理者のバウンスバックを管理したくありませんでした。管理者が私たちなしでバウンスと返信を見ることができるメッセージ受信ボックスを用意することにしました。管理者は調整に対処できます。必要に応じてメールアドレス。
このため、監視している受信トレイに送信されるすべての電子メールを受け入れます。VERPを使用して、電子メールをユーザーに関連付け、電子メール全体をそのままデータベースに保存します。次に、管理者が電子メールの表示を要求すると、電子メールを解析する必要があります。
私の最初の試みは以前の答えと非常に似ていました。パーツの1つがhtmlの場合は、それを表示します。テキストの場合は表示します。それ以外の場合は、元の生のメールを表示します。これは、sendmailによって生成されなかったいくつかの電子メールで非常に速く故障しました。Outlook、Exchange、およびその他のいくつかの電子メールシステムはそれを行わず、マルチパートを使用して電子メールを送信します。何度も掘り下げて調べた結果、問題が十分に文書化されていないように見えることがわかりました。MHonArcを調べ、RFC(RFC2045およびRFC2046)を読むことで、以下の解決策を決定しました。解析と表示の機能を簡単に再利用できなかったため、MHonArcを使用しないことにしました。これが完璧だとは言えませんが、私たちが使用したのは十分でした。
まず、メッセージを受け取り、Email::MIMEを使用して解析します。次に、パーツの配列を使用してget_partという関数を呼び出します。Email::MIMEは->parts()を提供します。
get_partは、渡されたパーツごとに、コンテンツタイプをデコードし、ハッシュで検索し、存在する場合は、そのコンテンツタイプに関連付けられた関数を呼び出します。デコーダーが何かを提供できた場合は、それを結果配列に配置します。
パズルの最後のピースは、このデコーダーアレイです。基本的に、それは私が扱うことができるコンテンツタイプを定義します:
- text / html
- テキスト/プレーン
- メッセージ/配信ステータス、これは実際にはプレーンテキストでもあります
- マルチパート/混合
- マルチパート/関連
- マルチパート/代替
非マルチパートセクションはそのまま返します。混合、関連、および代替の場合、そのMIMEノードでget_partsを呼び出すだけで、結果が返されます。代替は特別であるため、get_partsを呼び出した後にいくつかの追加コードがあります。html部分がある場合にのみhtmlを返すか、テキスト部分がある場合はテキスト部分のみを返します。どちらも持っていない場合、有効なものは返されません。
有効なコンテンツタイプのハッシュの利点は、必要に応じてより多くのパーツのロジックを簡単に追加できることです。そして、get_partsが完了するまでに、気になるすべてのコンテンツの配列ができているはずです。
私が言及しなければならないもう一つの項目。この一環として、これらのメッセージを実際に提供する別のドメインを作成しました。管理者が作業しているメインドメインは、メッセージの提供を拒否し、ブラウザをユーザーコンテンツドメインにリダイレクトします。この2番目のドメインは、ユーザーコンテンツのみを提供します。これは、ブラウザがメインドメインからコンテンツを適切にサンドボックス化するのに役立ちます。同一生成元ポリシーを参照してください(http://en.wikipedia.org/wiki/Same_origin_policy)