ステップメールとはメールマーケティングの手法のひとつです。ある時点(資料請求日、申込日、初回購入日など)を起点として、あらかじめ準備していた複数のメールをスケジュールに沿って順次配信する仕組みのことです。
ここではGoogle スプレッドシートとGASをつかって簡単にメルマガを配信する方法を紹介します。
「メール送信先」のシートにA列に苗字、B列に名前、C列にメールアドレス、D列に次回何日目の配信かを記録しておきます。そして毎日決められた時間になったらメールを送信します。
メルマガ登録の処理
まず登録用のフォームをつくります。それから後述するregist.phpを適当な場所にアップロードしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>登録用のフォーム</title> </head> <body> <form action="https://lets-csharp.com/samples/2109/mail/regist.php" method="get"> <label>苗字:</label><input type="text" name="lastname" id="lastname" required><br> <label>名前:</label><input type="text" name="firstname" id="firstname" required><br> <label>メールアドレス:</label><input type="text" name="email" id="email" required><br> <input type="submit" value="登録"> </form> </body> </html> |
登録ボタンをおすとアップロードしておいたphpに苗字、名前、メールアドレスが渡されます。そしてスプレッドシートの最後の行に登録者の苗字、名前、メールアドレスがセットされ、D列には「1」がセットされます。
PHPファイルは
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php $lastname = $_GET["lastname"]; $firstname = $_GET["firstname"]; $email = $_GET["email"]; $data = array( 'functionName' => 'Regist', 'lastname' => $lastname, 'firstname' => $firstname, 'email' => $email, ); // URL エンコード $data = http_build_query($data, "", "&"); // 送信時のオプション $options = array('http' => array( 'method' => 'POST', 'content' => $data, )); // ストリームコンテキストを作成 $options = stream_context_create($options); $url = 'https://script.google.com/macros/s/XXXXXXXXXXXXXXXXXXXXX/exec'; $contents = file_get_contents($url, false, $options); // {"value":"XXXX@address.jp を登録しました。"}という形で返されるため、返された文字列を置換する $contents = str_replace('{"value":"', '', $contents); $contents = str_replace('"}', '', $contents); echo $contents; |
そしてPostされたデータをGAS側で処理します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
function doPost(e){ if (e == undefined || e.parameter == undefined) return ReturnResult("引数がありません"); if(e.parameter.functionName == 'Regist') return Regist(e); if(e.parameter.functionName == 'Unregist') return Unregist(e); return ReturnResult("不正な引数"); } function ReturnResult(ret){ // 結果はJSONで返す let JsonData = {}; JsonData.value = ret; return ContentService.createTextOutput(JSON.stringify(JsonData)); } function Regist(e){ let lastname = e.parameter.lastname; let firstname = e.parameter.firstname; let email = e.parameter.email; let sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("メール送信先"); let rowNumber = 1; while(true){ rowNumber++; let address = sheet1.getRange(rowNumber,3).getValue(); if(address == '') break; if(address == email) return ReturnResult(email + ' はすでに登録されています。'); } sheet1.getRange(rowNumber,1).setValue(lastname); sheet1.getRange(rowNumber,2).setValue(firstname); sheet1.getRange(rowNumber,3).setValue(email); sheet1.getRange(rowNumber,4).setValue(1); return ReturnResult(email + ' を登録しました。'); } |
メルマガ解除の処理
それからメルマガを送信するのであれば登録解除の手段を提供するのがルールです。メルマガ本文の一番後ろに登録解除のためのリンクを設置します。https://lets-csharp.com/samples/2109/mail/unregist.php?email=XXXX@address.jpのようなリンクがつきます。そしてリンクをクリックするとリンク先のページに「XXXX@address.jp を登録しました」と表示され、スプレッドシートのメールアドレスに対応する部分に「解除」という文字列がセットされます。
unregist.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php $email = $_GET["email"]; $data = array( 'functionName' => 'Unregist', 'email' => $email, ); $data = http_build_query($data, "", "&"); $options = array('http' => array( 'method' => 'POST', 'content' => $data, )); $options = stream_context_create($options); $url = 'https://script.google.com/macros/s/XXXXXXXXXXXXXXXXXXXXX/exec'; $contents = file_get_contents($url, false, $options); // {"value":"XXXX@address.jp を登録しました。"}という形で返されるため、返された文字列を置換する $contents = str_replace('{"value":"', '', $contents); $contents = str_replace('"}', '', $contents); echo $contents; |
GASでは
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function Unregist(e){ let email = e.parameter.email; let sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("メール送信先"); let rowNumber = 1; while(true){ rowNumber++; let address = sheet1.getRange(rowNumber,3).getValue(); if(address == '') break; if(address == email){ sheet1.getRange(rowNumber,4).setValue('解除'); return ReturnResult(email + ' を解除しました'); } } return ReturnResult(email + ' は登録されていません。'); } |
メルマガ送信の処理
あとは時間になったらメールを送信できるようにするだけです。最後の行には解除用のリンクをいれておきます。よくメルマガには「解除すると再登録できなくなります」と書かれているものをみるのですが、これはシステム上、そのようにするしかないのでしょうか? それとも解除したら最後、二度と登録できなくなるので、読者に解除するのを思いとどめさせるためでしょうか?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
function SendEmails(){ let sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("メール送信先"); let sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("送信内容"); let rowNumber = 1; while(true){ rowNumber++; let name = sheet1.getRange(rowNumber,1).getValue(); if(name == "") break; let lastname = sheet1.getRange(rowNumber,1).getValue(); let firstname = sheet1.getRange(rowNumber,2).getValue(); let emailAddress = sheet1.getRange(rowNumber,3).getValue(); // D列には何回目の配信かが記載されている。 // この部分に「解除」などの数字以外のものが書かれていたらスキップする let count = sheet1.getRange(rowNumber,4).getValue(); if(isNaN(count)) continue; // 何回目の配信かがわかればメールの件名と本文を取得できる // メールの件名を取得する。{苗字}や{名前}がある場合は置き換える let subject = sheet2.getRange(count,1).getValue(); subject = subject.replace(/{苗字}/g, lastname).replace(/{名前}/g, firstname); // メールの本文を取得する。{苗字}や{名前}がある場合は置き換える let body = sheet2.getRange(count,2).getValue(); if(body != ''){ // その日に配信するメールの本文が存在する場合はメールを送信する。 // {苗字}や{名前}がある場合は置き換える body = body.replace(/{苗字}/g, lastname).replace(/{名前}/g, firstname); // 最後に解除用のリンクをつける body += '\n\n\nこのメルマガが不要であれば以下のリンクから解除できます。解除すると再登録できなくなります。\n解除用リンク ⇒ '; body += 'https://lets-csharp.com/samples/2109/mail/unregist.php?email=' + emailAddress; // メールを送信する GmailApp.sendEmail(emailAddress, subject, body); // デバッグ用にログを表示 console.log(name); console.log(subject); console.log(body); } else{ console.log(name + 'にメールは送られませんでした。'); } // 次回の配信のためにD列の数字を1増やす count++; sheet1.getRange(rowNumber,4).setValue(count); } } |