Customers Mail CloudのWebhookは2種類あります。
- メール受信時
- メール送信時
メール受信時のWebhookはその名の通り、メールを受け取った際に任意のURLをコールするものです。この記事では添付ファイル付きメールを受け取った際のWebhook処理について解説します。
<!—more—>
フォーマットはマルチパートフォームデータ
Webhookの形式として、JSONとマルチパートフォームデータ(multipart/form-data)が選択できます。この二つの違いは、添付ファイルがあるかどうかです。JSONの場合、添付ファイルは送られてきません。今回のようにメールに添付ファイルがついてくる場合は、後者を選択してください。
Go言語による実装
Go言語では以下のように作成します。今回はWebフレームワークとしてginを利用しています。まず、プロジェクトを作ります。
go mod init smtps/webhook
また、ginをインストールします。
go get -u github.com/gin-gonic/gin
ginを使った場合のコードは、外観として以下のようになります。今回は POST /mails
にてWebhookを受け取る前提になります。最後に必ずHTTPステータス200を返してください。
package main import ( "fmt" "io" // 添付ファイル用 "os" // 添付ファイル用 "strconv" // 添付ファイル用 "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.POST("/mails", func(c *gin.Context) { // この中で処理します c.JSON(200, gin.H{}) }) r.Run() // 0.0.0.0:8080 でサーバーを立てます。 }
送信されてくるデータについて
メールを受信すると、以下のようなWebhookが送られてきます(データは一部マスキングしています)。JSONにしていますが、実際にはmultipart/form-data
です。
{ "filter": "info@smtps.jp", "headers": [ {name: 'Return-Path', value: '<user@example.com>'}, : {name: 'Date', value: 'Thu, 27 Apr 2023 15:56:26 +0900'} ], "subject": "Webhookのテスト", "envelope-to": "user@smtps.jp", "server_composition": "sandbox", "html": "<div dir=\\\\\\\\\\\\\\\\"ltr\\\\\\\\\\\\\\\\">Webhookのテスト用メールです。<div>...</div></div>", "text": "Webhookのテスト用メールです。\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\n--\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\n...", "envelope-from": "info@smtps.jp", "attachments": 1, "attachment1": "...." }
実装について
multipart/form-data
の場合、まず c.MultipartForm()
を実行します。その後は c.Request.PostForm
にデータが入ってきます。
なお、各データは配列になっているので注意してください。
c.MultipartForm() for key, value := range c.Request.PostForm { fmt.Printf("%v = %v \n", key, value[0]) }
添付ファイルの存在確認
添付ファイルがあるかどうかは attachments
キーの値が1以上かどうかで判定できます。
attachments, err := strconv.Atoi(c.Request.PostForm["attachments"][0]) if err != nil { fmt.Println(err) } if attachments > 0 { // 添付ファイルあり }
添付ファイルをローカルに保存する
添付ファイルデータを受け取ってファイルとして保存する際には、以下のように処理します。
if attachments > 0 { // 添付ファイルあり file, header, err := c.Request.FormFile("attachment1") if err != nil { fmt.Println(err) } if file != nil { saveFile, _ := os.Create("./" + header.Filename) defer saveFile.Close() io.Copy(saveFile, file) } }
Webhookの結果は管理画面で確認
Webhookでデータが送信されたログは管理画面で確認できます。送信時のAPIキー設定など、HTTPヘッダーを編集するといった機能も用意されていますので、運用に応じて細かなカスタマイズが可能です。
まとめ
メールと連携したシステムはよくあります。通常、メールサーバを立てて、その中で処理することが多いのですが、メールサーバが落ちてしまうとシステムが稼働しなくなったり、メール文面の解析が煩雑でした。Customers Mail Cloudを使えばそうした手間なくJSONで処理できて便利です。
添付ファイルまで処理対象にしたい時には、この方法を利用してください。