emahiro/b.log

日々の勉強の記録とか育児の記録とか。

SES SendRawEmail API を使って画像付きメールを送信する

Overview

SES SendRawEmail API を利用して画像付きのメールを送信するための備忘録です。

実装について

基本的な実装方法については Amazon SES API を使用して raw E メールを送信する を参考にすればできます。

画像付きのメールを送信する上でポイントになるのは 添付ファイル のチャプターを参考にします。

E メールにファイルを添付するには、base64 エンコードを使用して添付ファイルをエンコードする必要があります。
添付ファイルは通常、次のヘッダーを含む専用の MIME メッセージ部分に配置されています。

- Content-Type: 添付ファイルの種類。一般的な MIME Content-Type 宣言の例を以下に示します。プレーンテキストファイル: Content-Type: text/plain; name="sample.txt"

- Microsoft Word ドキュメント: Content-Type: application/msword; name="document.docx"

- JPG イメージ: Content-Type: image/jpeg; name="photo.jpeg"

- Content-Disposition: 受取人の E メールクライアントがコンテンツをどのように処理するかを指定します。添付ファイルの場合、この値は Content-Disposition: attachmentです。

- Content-Transfer-Encoding: 添付ファイルのエンコードに使用されるスキーム。添付ファイルでは、ほとんどの場合この値は base64です。

ref: Amazon SES API を使用して raw E メールを送信する > 添付ファイル

Go での実装について

Go で実装するにはこのドキュメントで定義されているファイルを添付するための Header の定義を textproto.MIMEHeader{} の中に追加して、最後にこの Header を byte 配列に変換して扱います。

byte 配列は最終的に Amazon SES API を使用して raw E メールを送信する > MIME の使用で示されているようなサンプル文字列を []byte 配列にしたものを作ることができればOKです。

画像の添付方法について

上記 実装について で説明されている Content-Type を MIME header に追加します。ここでのポイントは Content-Transfer-Encoding ヘッダーには "base64" というデータ形式の名前が入ることです。

代表的なメール送信のリポジトリhttps://github.com/go-gomail/gomail/blob/81ebce5c23dfd25c6c67194b37d3dd3f338c98b1/writeto.go#L145 あたりを参考にしてましたがこれはデータの形式を指しているのではなく実際データを base64 に変換したものを追加するのかと思ってました。

実際にデータ本体を追加する場合は Content-Type, Content-Disposition, Content-Transfer-Encoding 追加の後一行空けて base64エンコードした画像を追加します。

Sample

--${BoundyString}
Content-Type: $ContentType; name="$FileName"
Content-Description: "$FileName"
Content-Disposition: attachment; filename="$FileName"
Content-Transfer-Encoding: base64
// 一行空ける
${Base64EncodedString}

これを Go のコードにすると以下になります。

header := textproto.MIMEHeader{}
header.Set("Content-Type", "image/png; name=sample.png")
header.Set("", "attachment; filename=sample.png")
header.Set("Content-Transfer-Encoding", "base64")

ちなみに最後の Content-Transfer-Encoding で全然うまくいかずに悩んでいるときに以下の StackOverflow のサンプルコードが役に立ちました。

stackoverflow.com

まとめ

そもそも Rawメールの構造を知らずに作っていたので添付ファイルをアタッチするときにどこにどうアタッチすれば、メールのクライアント(Gmalとかね)で読み込んでくれるのか頭を悩ませていましたが、一度作ってしまうとなるほどなーという感じでした。
たまたま仕事で使うことがあったのでドキュメント読み込みながらエンコードされたメールの生のフォーマットに触れてみることができてよかったです。

Refs

docs.aws.amazon.com

stackoverflow.com

github.com