購入後メールの自動化は、文面より先に「送らない条件」を決める
自動で送るメールは、送る前に人が目を通しません。送る・送らないの判断は、すべて事前に書いた規則が行います。
そのため、最初に決めたのは文面ではなく規則でした。起点、重複、遅れ、停止の4点です。
4通の役割
送るのは、購入直後、3日後、7日後、14日後の4通です。日数は目安で、提供を保証するものではありません。
- 0日目:ログインして使いはじめる入口。パスワード未設定、設定済み、リンク期限切れの3通りに分けて書いています
- 3日目:止まった場所を返信してもらう。準備、設定、実行、確認の4つのどれか、で足りるようにしています
- 7日目:最初の1件が仕事に使えたかを尋ねます
- 14日目:同じ仕事の2回目に使い回せたかを尋ねます。続けない判断なら、返信で以後の案内を止められます
どの回も、1通につき行動は1つだけです。価格は書きません。
送信の仕組み
決済は外部の決済サービスで受け、メールはメール配信サービスの API で1通ずつ送っています。送信の処理は Mac の定期実行で、1時間ごとに動きます。
大がかりな配信基盤は使っていません。そのぶん、送る・送らないの規則を、台帳とコードに明示しておく必要がありました。
ステップメールの起点は「決済の完了」だけにする
決済サービスからは、2種類のイベントが届きます。ひとつは決済の完了(チェックアウトの完了)、もうひとつは請求の支払いです。
請求の支払いは、初回にも毎月の更新にも届きます。これを起点にすると、更新のたびに案内が始まってしまいます。
「新規/更新」の判定を起点にしなかった理由
最初に思いつくのは、システム側の「新規」の判定を条件にする方法です。しかし、イベントの到着順は保証されていません。
初回の請求イベントが先に届くと、あとから届くチェックアウト側が「更新」と記録される順序があります。「新規」を条件にすると、この順序では初回の案内が始まりません。
そこで、案内を始める起点は決済の完了イベントだけにしました。「新規/更新」の判定は記録として残すだけで、送るかどうかの条件には使いません。到着順に依存しないことは、テストでも固定しています。
二重送信を防ぐ:台帳・再購入・冪等キー
二重送信を防ぐ層は3つあります。取り込みの重複、再購入、送信そのものの重複です。
取り込みの重複を台帳で止める
自前の台帳(JSON ファイル)に、購入ごとの記録を持ちます。同じ監査 ID と同じチェックアウトのセッションは、二度取り込みません。
同じイベントが再送されても、台帳に取り込む時点で止まります。
再購入は0日目だけ送る
同じメールアドレスの2件目以降は、再購入として扱います。再購入には0日目だけを送り、3日目・7日目・14日目は送りません。2026年9月21日に決めた扱いです。
再購入かどうかは、システム側の「更新」の判定ではなく、台帳にその人の記録があるかで決めています。
冪等キーで通信の失敗に備える
送信は1人ずつ、次の順で行います。
- 送る予定を台帳に保存する
- 送信する
- 結果を台帳に保存する
送信には冪等キー(同じ依頼を二度受けても1回として扱わせる値)を付けます。購入のセッションと回の組み合わせで一意にし、たとえば「pp:セッション:d3」のような形です。
結果は3通りに分けて扱います。
- 成功:送信記録を残す
- HTTP エラー:明確な失敗なので予定を消し、次回また送る
- 通信例外:届いたかどうか分からないので予定を残し、24時間以内は同じキーで再試行する
受理済みだった場合、メール配信サービスは同じ ID を返し、二通目は出ません。24時間を過ぎるとキーの保持期間が切れるため、送り直しはしません。「unknown_result(結果不明)」として閉じ、人が送信履歴で確かめます。
再チェックで見つかった不具合1:成功記録の消失
再チェック前の実装では、全員分をまとめて最後に台帳へ保存していました。そのため1人で通信例外が起きると、他の人の成功記録まで保存されず、翌時の実行で送り直す作りでした。
2026年9月21日に、1人ずつ保存する形へ直しました。購入者に届く前の再チェックで見つかったものです。
遅れて届く購入後メールを防ぐ「送る窓」
本文には「3日ほど」「1週間ほど」「2週間ほど」と経過日数を書いています。実際の経過日数とずれて届くと、本文の内容が事実と合わなくなります。
回ごとに送る期間を区切る
契約からの経過日数で、各回を送ってよい期間(窓)を決めています。
- 3日目:3日以上7日未満
- 7日目:7日以上14日未満
- 14日目:14日以上28日未満
窓を過ぎた回は送らず、「stale(期限切れ)」として台帳に残します。0日目のログイン案内だけは、経過日数に関係なく送ります。
さらに、同じ人への実際の送信は2日以上空けます。通常の 0→3→7→14 の順なら間が3日・4日・7日空くので、この規則が効くのは遅れて再開したときだけです。
再チェックで見つかった不具合2:復帰後の連続送信
例を挙げます。0日目を送った後にパソコンが止まり、15日後に復帰したとします。今の規則では、3日目と7日目は窓を過ぎているので閉じ、14日目だけを1通送ります。
2026年9月21日の再チェック前は、復帰後に1時間おきに3日目、7日目、14日目を続けて送る作りでした。窓と間隔の規則を入れて直しています。これも購入者に届く前に見つかったものです。
1回の実行で、1人に送るのは最大1通
1回の実行で1人に送るのは、最大1通です。0日目が未送なら、それを最優先にします。
止めてほしい人に送らない:停止・同時実行・ニュースレターとの関係
自動送信で避けたいのは、止めてほしいと伝えた人にさらに送ることです。
停止の条件
次の場合は、以後の回を送りません。
- 本人が「案内不要」と返信した
- 解約や返金の申出があった
利用を開始済みと分かった人には、3日目の督促を送りません。
結果不明の予定が残っている人に停止の印が付いた場合は、再試行せずにその回を閉じます。停止を、再試行より先に判定しています。
同時実行はロックファイルで1本に絞る
台帳を書く実行は、ロックファイルで1本に絞ります。1時間ごとの定期実行と、手で記録を付ける操作が重なることがあるためです。
30分より古いロックは、途中で落ちた実行の残骸とみなして引き取ります。
ニュースレターとの線引き
購入は、ニュースレター配信への同意ではありません。そのため、メール配信サービスに連絡先が無い購入者の連絡先は作りません。
購入時のメールアドレスと、ニュースレター登録のメールアドレスが同じとは限りません。決済時に登録者の識別子が渡ってきた場合はそれだけで照合し、無い場合だけメールアドレスで探します。確認済みの登録者1人に特定できたときだけ「購入者」の印を付け、ニュースレター側の販売の案内を止めます。
該当が0人・複数・未確認のときは自動で結ばず、人に1回だけ知らせます。氏名などから推測して紐づけることはしません。
印の反映は1時間ごとなので、決済した瞬間に止まるわけではありません。
購入後メールは、契約に基づく取引メールとして送ります。ニュースレター用の配信解除リンクの差し込みが残っていたら、送信前に例外で止めます。解除リンクは一斉配信のときにしか差し込まれず、そのまま送ると壊れた文字列が出るためです。
購入後フォローメールを自動化する前に決める5項目
自分で作る場合、文面の前に決めておく項目は次の5つです。
- 起点:到着順が保証されない判定は条件に使わず、決済の完了だけを起点にする
- 窓:本文に書く経過日数と合うように、回ごとに送る期間を区切る。過ぎた回は送らず記録に残す
- 冪等キー:購入と回の組み合わせで一意にし、結果不明のときの再試行の期限(ここでは24時間)と閉じ方を決める
- 停止:停止の申出が、再試行より先に効くようにする
- ニュースレターとの関係:購入を配信同意とみなさず、1人に特定できたときだけ印を付ける。特定できなければ人に渡す
現時点で確認できていないこと
起点・重複・窓・冪等キー・停止の規則は、テスト15件に書いて固定しています。ただし、この記事を書いた時点では、テストの実行結果を確かめていません。
2026年9月21日の記録では、台帳に入った購入は0件でした。この起点で数える購入がまだ無く、購入者への本番の配信は確認できていません。
それより前の購入者10件は、台帳に履歴がありません。そのため、この人たちが再購入すると初回として扱われる制約が残っています。手で再購入と記録するか、3日目を止める運用で対応します。
開封率や返信率などの成果の数字は、まだありません。成果は「本人が選んだ1つの業務で、実際の入力から出力を作り、確認して仕事に使えると判断した状態」と定め、本人の返信と台帳で確かめる予定です。返信が無い人は「未達成」ではなく「不明」として扱います。
