メール送信機能に関する失敗談と個人的勘所


この記事は[【CPaaS】SMS・メール機能の開発・運用でのやらかし談＆失敗エピソード募集 by ネクスウェイ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/cpaas-now) の22日目の記事です。

## メールアドレスにHotmail(Outlook)を使うユーザーが想定される場合はSendGridを使うな

### 何が起こったか

TypeScriptのアプリからFirebaseを経由してメールリンク認証を作ってました。

FirebaseではAuthanticationにメールでサインイン用のリンクを送るだけでOKなパスワード不要のログイン方法が存在します。
このメールの送信元は基本的に独自ドメインを使うことになると思いますが、その際にSMTPの設定が必要となります。
SendGridを使って独自ドメインの認証も済ませたあと、自分のHotmailのメールアドレスに認証メールを送っても一向に届かないという現象が発生しました。

### 解決策

#### 潔く課金する

似たような現象のフォーラムを見つけて来ました。

https://forum.bubble.io/t/sendgrid-emails-not-being-sent-to-hotmail/129107/2

SendGridは無料版だと送信元のIPが固定ではなく動的に決まるらしく、IPの範囲によって特定のドメインのメールサーバーで弾かれるとのことでした。
なので固定IPを振ってくれるように有償課金することでこの現象は回避できるそうです。


#### 他のCPaaSを使う

国内だと [blastengine](https://blastengine.jp/)が代替候補になると思います。
他にも上述したフォーラムに記載されているような海外サービスPostmark、Sendinblue、MailChimpあたりでも良さそうです。

#### 自前でなんとかする

自前のメールサーバーを構築するパターンも一応ありますが、まぁ仮想化・クラウドサービス全盛期の現代において、メールサーバーを独自構築することにかなりのメリットがあるプロダクトでない限り、選択肢には上がりづらいかと思います。

あるとすればマーケティングDX系のサービス、広告配信基盤、コミュニケーションサービス連携（LINE、メール、X、Instagramなどのメッセージを管理するやつ）とかそういうやつでしょうか。

## メールテンプレートを使うときは熟考する

### 何が起こったか

SendGridにはメールのテンプレート機能が存在します。これはSendGrid側で作成・管理することができ、メール送信時のAPIに `template_id` を指定するだけで完了するというなんとも素敵なサービスです。

https://sendgrid.kke.co.jp/docs/Tutorials/A_Transaction_Mail/using_dynamic_templates.html

もちろん国産のメール配信サービスであるbrastengineにも同様の機能があります。

ただ、安直にこのサービスを使ってしまうと少し大変なことが発生します。

### メールテンプレート機能の問題点

#### テンプレートの管理が煩雑化する

テンプレートを複数利用し始めると、管理が難しくなることがあります。
例えば以下のような感じです。

- 同じ内容の修正を複数のテンプレートに適用しなければならない場合、修正漏れが発生
- どのテンプレートがどのメールに対応しているのか追跡が困難

よくExcelやスプレッドシートでもこの問題は起きがちですよね。 __「（最新）2024年XX管理_tmp.xlsx」や「【更新不可】XXXXX_20241222.xlsx」__ みたいに、もはや最新なのかtemporaryなのかリードオンリーなのか開くまで分かりません（開いてもわからない可能性大）（笑

#### バージョン管理が不十分

SendGridでは各メールテンプレートをバージョン管理（複製や新規作成も可能）することができますが、他のサービスではできないという場合もあるようです。
バージョン管理ができないと過去と現在との差分がわからないため、変更の影響範囲やテンプレートのちょっと不具合が発生しても原因究明に時間がかかるようになります。
よくある例だと「XXXさま　にお知らせ」というメール冒頭部分で、名前が全員「{{account_name}}さま」という感じで変数のまま送信されるパターンですね。


#### テストメールミス

メールはインサービスのテンプレートを使っていると、実際のメールを送信するときにGUI操作を誤ってしまって全員にテストメールを送ってしまうパターンがあります。私自身も年間1通くらいはどこかの企業から誤配信メールを受け取っている気がします。


#### サービス依存リスクが高すぎる

メール配信サービスを選定した理由が __「独自ドメインのSMTPのリレーを自社構築・保守する手間を省く」__ という場合、そもそも特定のメール配信サービスのテンプレート機能に依存することそのものがリスクになり得ます。
「もっと安い別のサービスに移行したいのに、テンプレートをすべて移行し直す必要があって時間がかかる」という状況に陥るからです。
メール配信サービスに限らず、外部サービスについては「目的は何なのか」を見定めて、それを忘れないように使用することが大切です。

### 解決策

#### テンプレート管理の標準化

まずはルールを設けてしまえという対策です。
例えば「テンプレートの命名規則」「修正・バージョン追加時の対応プロセス」「テスト配信時のチェックリスト」とかですね。
ただ、組織が大きくなるとルールも形骸化しやすいですし根本対策とは言い難いかなと。


#### エンジニアと協力する

すでにメールテンプレートを使っていて、かつユーザー独自の変数（ユーザー名、企業名をメール文面に載せるなど）がある場合、そもそもその変数をAPIで渡せるようにエンジニアと一部協力しているはずです。
であれば、メールテンプレートそのものもエンジニア側に管理してもらえば色々解決するという対策です。

例えば最新のテンプレートのコードをコピペしてエンジニアに提供し、メール送信機能をもつプロダクトと一緒にGit管理してもらうとかです。
もっと発展させれば、そもそもテンプレート機能そのものをAdminツールとしてエンジニアに作ってもらっても良いかもしれません。API経由で独自変数を格納する実装ができるレベルのエンジニアチームがいるのであれば、このくらいは余裕でできるはずです。

同様に、テスト配信もエンジニアサイドにフールプルーフな実装で作成してもらうと良いでしょう。
そうすればたとえ何度テスト配信しようとも、実ユーザーに対して送信されるメールを撃滅することが可能です。


## まとめ

メール配信サービスは非常に便利な機能ですが、選定の目的と運用方法には注意が必要です。
特に、便利な機能だからといってガンガン使っていると、それはそれでベンダーロックインに陥りやすくなります。（サービス提供者からすると嬉しい限りですが……）

社内にエンジニアチームがいるのであれば最大限協力し社内でのDX化と共通認識・共通基盤化を進めていくことで無駄なコスト（管理、サービス費用、運用など）を省くこともできると思います。