MTA含めてハマりまくったので記録しておきます。
ローカルMTAを使う場合、
現在の最新lettre 0.10-alphaの場合、
SmtpTransport::unencrypted_localhost();
0.9の場合、
SmtpClient::new_unencrypted_localhost().unwrap().transport();
但し、Dockerで25portをバインドしてlocal配送を試みた場合、relayの設定でハマりまくってしまって(多分、ホスト側からのリレー許可が必要?172.17.0.1からのリレーを許可すればいけそうな気がしたがダメだった)解決しなかったので、結局、Gmailをリレーするようにした。
ここから本題。lettreで日本語メールを送信する
まず、最新のlettre 0.10.0-alpha.1
はlettre_email
が統合され、Emailというインスタンスでメッセージをbuildしていくようになっているようです。このEmail
、タイトルは日本語表記できるんだけど、本文に日本語を記述するとNonAsciiChars
とエラーが表示される笑
Rust lettre、subjectには日本語使えるんだけど、本文に使うとNonAsciiCharsエラーがでる笑
— Fumiya Ichikawa (@LET__IT__RIDE) December 30, 2020
lettre_email使いたいんだけど、今のlettreのバージョンと互換がないんだけど。https://t.co/iM605haebr
なので、0.9系のlettreを使用して日本語メールを送信するようにした。
lettre 0.9系でのメール送信
Cargo.toml
lettre = "0.9" lettre_email = "0.9"
lettreはバージョンごとに細かいインターフェースの仕様が変わっているようで、読むドキュメントによって結構メソッド名やcrateのパスが違ったりする。僕の場合、GitHubのreadmeのバージョンを遡って読んでいきようやく動作する書き方を判断した。
実装例はgmailのMTA利用例。認証ユーザ名は@gmail
つきで。
send.rs
extern crate lettre; extern crate lettre_email; use lettre::smtp::authentication::Credentials; use lettre_email::EmailBuilder; use lettre::{SmtpClient, Transport}; pub fn send() > { let email = EmailBuilder::new() .to(("to@example.com", "Firstname Lastname")) .from("from@example.com") .subject("日本語のタイトル") .text("日本語の本文") .build() .unwrap(); let creds = Credentials::new("user@gmail.com".to_string(), "password".to_string()); let mut mailer = SmtpClient::new_simple("smtp.gmail.com") .unwrap().credentials(creds).transport(); // Send the email let _ = mailer.send(email.into()); }
上記で日本語メールの送信が確認できた。
use lettre::{SmtpClient, Transport};
は、use lettre::smtp
のパスではないので注意。lettre::smtpだとprivate traitになる。また、Transport
はsendメソッドを提供している。
タイトルは日本語だとおかしくなるというQiitaの記事を見たが、現在だと修正されている模様。
また、中のコードを読めば分かるんだけど、new_simple
は
pub const SUBMISSIONS_PORT: u16 = 465;
に認証を取りにいくみたい。
また、SmtpTransport
にrelay
というpubメソッドがあって、こちらを使用すると思ったんだけど、何故かfunction undefinedになって利用の仕方がわからなかった。
ローカル配送を行う場合は、前述の通り、
new_unencrypted_localhost()
を使用すればよい。と思う。ただ、Dockerで立てたMTAに対してはどうしてもリレーの設定がわからなかった笑