lettreで日本語メールを構築するとき、以下のように書くと思います。
use lettre_email::{Email, EmailBuilder};
fn build_email() -> EmailBuilder {
EmailBuilder::new()
.from(("hoge@example.com", "ほげ"))
.to("fuga@example.com")
.subject("テストメール")
.text("テスト")
.build().unwrap()
}
しかし、このように書いた場合、不正なメールが生成されます。
Subject: テストメール
To: <fuga@example.com>
From: "ほげ" <hoge@example.com>
...
テストメール
一見問題なさそうですが、実はこのメール、ヘッダに問題があります。
というのも、本来メールヘッダにはASCII文字以外が勝手に出現してはならないのです。
UTF-8文字などをヘッダに使いたい場合、正常なクライアントならば以下のようにMIMEエンコードを行います。
Subject: =?UTF-8?B?44OG44K544OI?=
これは公式に定められたエンコード方式で、Base64で文字列をエンコードしています。
自前でエンコードしてみる
lettreに修正を依頼するより自分で直すが早そうな気がするので適当に書いてみます。
// 別途base64クレートが必要
use lettre_email::{Email, EmailBuilder};
fn mime_encode(txt: &str) -> String {
format!("=?UTF-8?B?{}?=", base64::encode(txt.as_bytes()))
}
fn build_email() -> Email {
EmailBuilder::new()
.from(("hoge@example.com", mime_encode("ほげ")))
.to("fuga@example.com")
.subject(mime_encode("テストメール"))
.text("テスト")
}
lettre自体が単に与えられた文字列を埋め込んでるだけっぽかったのでうまく動いたみたいです。
とりあえずはこれで良しとしましょう。
気づいたきっかけ
DKIMありのメールサーバーでメールを送信したときになぜかlettreから送ったときだけ検証が失敗するのでおかしいとなり、
通常のメールクライアントの出力と比較したところこの点に気づきました。