サービスごとに別のメールアドレスを使いたいことがある。

最初はエイリアスを発行して、届いたメールを見られれば十分だと思っていた。実際に触ると、どのアドレスに届いたのか、リンクを開いてよいのか、古いメールをいつ消すのかまで見たくなる。

そこで、個人用の小さなメールエイリアス管理ツールを作っていた。

受信と管理画面を分ける

構成は、メールを受け取る Worker と、管理画面から操作する Worker を分けた。

受信側では、エイリアスを引いてメタデータを D1 に保存し、元の MIME は R2 に置く。管理画面側は D1 の状態を見て、エイリアスやメッセージの一覧を出す。

メール
  ↓
受信 Worker
  ├─ D1: エイリアス・メッセージ・監査ログ
  └─ R2: raw MIME
          ↓
      管理 Worker / 管理画面

本文を全部データベースに詰めるより、検索や一覧に必要な情報と元データを分けた方が扱いやすそうだった。

エイリアスの状態を増やす

エイリアスは作ったら終わりではなかった。

発行、停止、再開、アーカイブ、ローテーションを操作できるようにした。停止したものを誤って再利用しない、アーカイブしたものを一覧から適切に隠す、といった状態の扱いが地味に大事になる。

最初は一覧の表示条件だけで考えていたけど、状態遷移として考えた方が、受信時の判定や CSV 出力の条件も揃えやすかった。

受信箱として必要だったもの

メールを保存するだけでは、受信箱としては少し足りない。

未読、検索、サービス別の絞り込み、メッセージのリンク抽出、怪しそうな URL の警告を追加した。通知もブラウザから出せるようにした。

リンク抽出は便利そうだけど、それ自体を安全判定にしてはいけない。あくまで「このメールに URL が含まれている」と気づくための補助情報として表示することにした。

後から、監査ログの画面遷移や受信箱のフィルターも見直した。操作履歴が残っていると、なぜそのエイリアスが停止中なのかを追える。

送信も必要になる

受け取ったメールを表示できると、そこから返信や転送もしたくなる。

送信元を設定可能にし、送信処理と通知処理を追加した。ここでは、受信したメッセージをそのまま送信できると考えず、誰のエイリアスから、どの送信元を使って送るのかを別に確認する必要があった。

受信側のアドレス管理と、外向きメールの送信者管理は似ているようで別の機能だった。

モバイルと CSV で細かく詰まる

管理画面はデスクトップだけで見るものではなかったので、アカウント詳細画面をスマホ幅でも見直した。メールアドレスをコピーする操作も、入力欄のように見えないと分かりにくい。

エイリアスの台帳を CSV に出す処理では、画面の一覧と同じルーティング条件を通っていない不具合があった。表示側のデータが正しくても、出力側で別の集合を見ていた。

一覧、CSV、保持削除のような「同じデータを使う処理」は、同じスコープと取得条件を共有した方がよさそうだった。

保持期限を過ぎたメッセージを消す時は、先に D1 の記録を基準にし、対応する R2 の孤立オブジェクトも掃除するようにした。ストレージだけ残るケースを放置すると、後で何が残っているのか分からなくなる。

おわり

メールエイリアスの発行だけなら小さい機能に見えるけど、実際には受信箱、監査、送信、通知、保持削除がつながっていた。

個人用の道具なので、最初から大きなメールサービスにするつもりはない。それでも、認証境界、データの所有範囲、状態遷移を曖昧にすると、すぐに管理しづらくなる。

次は、メッセージの検索をどこまで D1 で持つか、受信失敗や再送をどう見せるかを考えたい。小さい管理画面でも、運用の入口を作ると見る場所が増えるみたいだ。