【GAS】大量にメール送信する際の注意点

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【GAS】大量にメール送信する際の注意点

2021-11-22 |

Google Apps Scriptを使って、大量にメール送信する際の注意事項です。

本業で、グループメールを使わず、多くの宛先(1,000件程)にそれぞれメールを送信する必要があったことがありました。この記事はその時の思い出です。

信じられないかもしれませんが、世の中には、ユーザー自身でパスワード変更ができない、且つ、アカウント発行時のメール送信機能がないサービスがあって、窮地をなんとか GAS を使って凌いだというか他のしわ寄せを食らったというか…。本当に勘弁。

注意点

  • 1日に送信できるメールの件数
  • メール送信とメール送信の間で一定時間休ませる+α
  • ちゃんとテストする!

それぞれざっくり説明してく。

1 日に送信できるメールの件数

まず、1 日に何件メールを送信できるのか?

何件までという件数による制限ではなく、Gmailのアカウントの種類によってそれぞれ割り当てられた数があって、*「宛先(To, Cc, Bccはそれぞれ別カウント) メールの件数」**分が 1日に送信できるメールの件数になる。

メール送信する度に宛先の数分、割当を消費する。

Gmailのアカウントの種類による割当は下記のようになる。

無料の一般の Gmail アカウント

500 = 宛先(To, Cc, Bcc)* メールの件数

有料の Google Workspace のアカウント

1,500 = 宛先(To, Cc, Bcc)* メールの件数

宛先の設定によるメール送信できる数の例を示す。

宛先が単数の場合

To1人にのみメール送信する場合、割当のうちの1を消費する。ということは、1日に割当の数分メールを送信できることになる。

無料の一般のGmailアカウントであれば、1日に500件、有料のGoogle Workspaceのアカウントであれば、1日に1500件のメール送信できる。

宛先が複数の場合

例えば、Toに担当者1人、Ccに関係者3人、Bccに同僚1人を設定したメールを1件送信すると割当のうち5を消費する。

同じ構成で何度がメール送信する場合、無料の一般のGmailアカウントであれば、1日に100件、有料のGoogle Workspaceのアカウントであれば、1日に300件のメール送信できる。

残りの割当を確認する

残りの割当を確認したい場合、下記のコードで確認できる。

function gas_sendmail_max()
{
    var mail_max = MailApp.getRemainingDailyQuota();
    Logger.log(mail_max);
}

上記のgas_sendmail_max では、MailApp.getRemainingDailyQuota で残りの割当を取得して、実行ログに出力してる。

メール送信とメール送信の間で一定時間休ませる+α

GmailApp.sendEmail を使用することでGASでメール送信することができるんだけど、絶え間なくこの関数を実行してしまうとエラーで止まってしまうので、Utilities.sleep で一定時間処理を止めて休ませる。

下記は、スプレッドシートから宛先などを読み込んで for で繰り返しメール送信をすることを想定した仮のコードです。本番ではちゃんとエラー処理とかしましょうね。

var sheet_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var sheet_name = "sendlist";

function sendmail()
{
    // スプレッドシートのID
    var spreadsheet = SpreadsheetApp.openById(sheet_id);
    // スプレッドシートのシート名
    var sheet = spreadsheet.getSheetByName(sheet_name);

    var h = sheet.getLastRow();
    var range = sheet.getRange(1, 1, h, sheet.getLastColumn());
    var v = range.getValues();

    // シートの1行目は項目名が入っているとして2行目から繰り返し処理を行う
    for (var i = 1; i < h; i++) {
        // C列にはメール送信に成功した際に送信日時が入力されるものとする
        // 既に送信済みの場合は送信しない
        if (v[i][2] == "") {
            GmailApp.sendEmail(
                // A列にメールアドレスが入力されてるものとする
                v[i][0],
                "【GAS】テストメール",
                // B列に氏名などの宛名が入力されてるものとする
                v[i][1] + "さんへ\n\nテストメールだよ!",
                {
                    name: "テストメール担当",
                    noReply: true
                });

            // メール送信に成功した際にC列に送信日時を入力する
            var dt = new Date;
            sheet.getRange(i + 1, 2 + 1).setValue(dt);

            // 1秒休む
            Utilities.sleep(1000);

            // テスト用
            // 繰り返しを3回目で止める
            // リストの上位3名を関係者にしておいて、テストメールを送信してみるとか
            //if (i > 3) {
            //  break;
            //}
        }
    }
}

メール送信後にUtilities.sleep(1000);で1秒休ませてる。引数の単位はミリ秒。

休ませてもメール送信に失敗する可能性がある

1秒休ませた場合でも稀にエラーが発生することがあるので、メールの送信した場合は送信が成功した日時をシートに記録しておき、もう一度コード実行した際に送信済みの宛先には送信せず、未送信の宛先のみにメール送信されるような設計にしておくと諸々楽です。

ちゃんとテストする!

コードを書いて、初回でちゃんと意図通り完璧に動くことってあんまりないと思います。
なので、ちゃんとテストをしましよう!
1000人に間違った内容でメールが送信されてしまうとなるとなかなかの規模のインシデントです。

前述のサンプルコードの中に記載していますが、ある程度コードが完成したら、まず、関係者数名にのみメール送信してみるとか。

引用・参考文献

REFERENCE - Google Apps Script