GASでメール一括送信の送信のマクロを作成し、本番稼働の日に「Exception:Service invoked too many times for one day : email.」というエラーが発生しました。400通ほど送信予定であったため、最終的に4日ほど遅延して終了しました。そして、今、ようやく落ち着きましたので、それがテスト時に確認できたのかどうか検証してみます。
検証
この現象が発生したのがGoogleFormの回答に対して実行しているマクロであったため、このテストマクロもスプレッドシートに対して読み書きしています。スプレッドシートで設定しているループ回数や「未送信」のステータスについては割愛させていただきます。
function myFunction() {
var sh = SpreadsheetApp.getActiveSheet();
var rg = sh.getDataRange();
var rows = rg.getLastRow(); // 最終行を取得
var values = rg.getValues(); // データを配列に格納
var spreadsheet = SpreadsheetApp.getActive();
var now = new Date();
var rows = values[0][0];// FOR文を何回転させるか
Logger.log("送信件数=" + rows);
for (var i = 1; i < rows + 1; i++) {
Logger.log("処理回数=" + i + ",ステータス=" + values[i][3]);
if ('未送信' == values[i][3]) {
var mail_to = "naoki.omata.omarnya+test@gmail.com"; // メール
var subject = "テスト" + i + "番目"; // 件名
var body = values[i][1]; // 本文
// createDraftは下書き, sendEmailはメール送信まで
GmailApp.sendEmail(mail_to, subject, body);
spreadsheet.getRange('C' + (i + 1)).activate();
spreadsheet.getCurrentCell().setValue(now.toString());
spreadsheet.getRange('D' + (i + 1)).activate();
spreadsheet.getCurrentCell().setValue('メール送信完了');
Logger.log(MailApp.getRemainingDailyQuota())
}
}
}
それでは、実行時のログです。元々は色がついていたのですが、テキストとしてコピーしたため、色を付けることができなかったのが、残念です。
実行ログ
22:28:29 お知らせ 実行開始
22:28:28 情報 送信件数=200
22:28:28 情報 処理回数=1,ステータス=未送信
22:28:29 情報 99.0
22:28:29 情報 処理回数=2,ステータス=未送信
22:28:30 情報 98.0
22:28:30 情報 処理回数=3,ステータス=未送信
22:28:30 情報 97.0
22:28:30 情報 処理回数=4,ステータス=未送信
22:28:31 情報 96.0
22:28:31 情報 処理回数=5,ステータス=未送信
22:28:34 情報 95.0
22:28:34 情報 処理回数=6,ステータス=未送信
22:28:35 情報 94.0
22:28:35 情報 処理回数=7,ステータス=未送信
22:28:35 情報 93.0
22:28:35 情報 処理回数=8,ステータス=未送信
22:28:36 情報 92.0
22:28:36 情報 処理回数=9,ステータス=未送信
22:28:39 情報 91.0
22:28:39 情報 処理回数=10,ステータス=未送信
22:28:40 情報 90.0
22:28:40 情報 処理回数=11,ステータス=未送信
22:28:41 情報 89.0
22:28:41 情報 処理回数=12,ステータス=未送信
22:28:41 情報 88.0
22:28:41 情報 処理回数=13,ステータス=未送信
22:28:44 情報 87.0
22:28:44 情報 処理回数=14,ステータス=未送信
22:28:45 情報 86.0
22:28:45 情報 処理回数=15,ステータス=未送信
22:28:46 情報 85.0
22:28:46 情報 処理回数=16,ステータス=未送信
22:28:46 情報 84.0
22:28:46 情報 処理回数=17,ステータス=未送信
22:28:49 情報 83.0
22:28:49 情報 処理回数=18,ステータス=未送信
22:28:50 情報 82.0
22:28:50 情報 処理回数=19,ステータス=未送信
22:28:51 情報 81.0
22:28:51 情報 処理回数=20,ステータス=未送信
22:28:51 情報 80.0
22:28:51 情報 処理回数=21,ステータス=未送信
22:28:54 情報 79.0
22:28:54 情報 処理回数=22,ステータス=未送信
22:28:55 情報 78.0
22:28:55 情報 処理回数=23,ステータス=未送信
22:28:56 情報 77.0
22:28:56 情報 処理回数=24,ステータス=未送信
22:28:56 情報 76.0
22:28:56 情報 処理回数=25,ステータス=未送信
22:28:59 情報 75.0
22:28:59 情報 処理回数=26,ステータス=未送信
22:29:00 情報 74.0
22:29:00 情報 処理回数=27,ステータス=未送信
22:29:01 情報 73.0
22:29:01 情報 処理回数=28,ステータス=未送信
22:29:01 情報 72.0
22:29:01 情報 処理回数=29,ステータス=未送信
22:29:04 情報 71.0
22:29:04 情報 処理回数=30,ステータス=未送信
22:29:05 情報 70.0
22:29:05 情報 処理回数=31,ステータス=未送信
22:29:06 情報 69.0
22:29:06 情報 処理回数=32,ステータス=未送信
22:29:07 情報 68.0
22:29:07 情報 処理回数=33,ステータス=未送信
22:29:09 情報 67.0
22:29:09 情報 処理回数=34,ステータス=未送信
22:29:10 情報 66.0
22:29:10 情報 処理回数=35,ステータス=未送信
22:29:11 情報 65.0
22:29:11 情報 処理回数=36,ステータス=未送信
22:29:12 情報 64.0
22:29:12 情報 処理回数=37,ステータス=未送信
22:29:14 情報 63.0
22:29:14 情報 処理回数=38,ステータス=未送信
22:29:15 情報 62.0
22:29:15 情報 処理回数=39,ステータス=未送信
22:29:16 情報 61.0
22:29:16 情報 処理回数=40,ステータス=未送信
22:29:17 情報 60.0
22:29:17 情報 処理回数=41,ステータス=未送信
22:29:19 情報 59.0
22:29:19 情報 処理回数=42,ステータス=未送信
22:29:20 情報 58.0
22:29:20 情報 処理回数=43,ステータス=未送信
22:29:21 情報 57.0
22:29:21 情報 処理回数=44,ステータス=未送信
22:29:22 情報 56.0
22:29:22 情報 処理回数=45,ステータス=未送信
22:29:24 情報 55.0
22:29:24 情報 処理回数=46,ステータス=未送信
22:29:25 情報 54.0
22:29:25 情報 処理回数=47,ステータス=未送信
22:29:26 情報 53.0
22:29:26 情報 処理回数=48,ステータス=未送信
22:29:27 情報 52.0
22:29:27 情報 処理回数=49,ステータス=未送信
22:29:29 情報 51.0
22:29:29 情報 処理回数=50,ステータス=未送信
22:29:30 情報 50.0
22:29:30 情報 処理回数=51,ステータス=未送信
22:29:31 情報 49.0
22:29:31 情報 処理回数=52,ステータス=未送信
22:29:32 情報 48.0
22:29:32 情報 処理回数=53,ステータス=未送信
22:29:34 情報 47.0
22:29:34 情報 処理回数=54,ステータス=未送信
22:29:35 情報 46.0
22:29:35 情報 処理回数=55,ステータス=未送信
22:29:36 情報 45.0
22:29:36 情報 処理回数=56,ステータス=未送信
22:29:37 情報 44.0
22:29:37 情報 処理回数=57,ステータス=未送信
22:29:39 情報 43.0
22:29:39 情報 処理回数=58,ステータス=未送信
22:29:40 情報 42.0
22:29:40 情報 処理回数=59,ステータス=未送信
22:29:41 情報 41.0
22:29:41 情報 処理回数=60,ステータス=未送信
22:29:42 情報 40.0
22:29:42 情報 処理回数=61,ステータス=未送信
22:29:44 情報 39.0
22:29:44 情報 処理回数=62,ステータス=未送信
22:29:45 情報 38.0
22:29:45 情報 処理回数=63,ステータス=未送信
22:29:46 情報 37.0
22:29:46 情報 処理回数=64,ステータス=未送信
22:29:47 情報 36.0
22:29:47 情報 処理回数=65,ステータス=未送信
22:29:49 情報 35.0
22:29:49 情報 処理回数=66,ステータス=未送信
22:29:50 情報 34.0
22:29:50 情報 処理回数=67,ステータス=未送信
22:29:51 情報 33.0
22:29:51 情報 処理回数=68,ステータス=未送信
22:29:52 情報 32.0
22:29:52 情報 処理回数=69,ステータス=未送信
22:29:54 情報 31.0
22:29:54 情報 処理回数=70,ステータス=未送信
22:29:55 情報 30.0
22:29:55 情報 処理回数=71,ステータス=未送信
22:29:56 情報 29.0
22:29:56 情報 処理回数=72,ステータス=未送信
22:29:57 情報 28.0
22:29:57 情報 処理回数=73,ステータス=未送信
22:29:59 情報 27.0
22:29:59 情報 処理回数=74,ステータス=未送信
22:30:00 情報 26.0
22:30:00 情報 処理回数=75,ステータス=未送信
22:30:01 情報 25.0
22:30:01 情報 処理回数=76,ステータス=未送信
22:30:02 情報 24.0
22:30:02 情報 処理回数=77,ステータス=未送信
22:30:04 情報 23.0
22:30:04 情報 処理回数=78,ステータス=未送信
22:30:05 情報 22.0
22:30:05 情報 処理回数=79,ステータス=未送信
22:30:06 情報 21.0
22:30:06 情報 処理回数=80,ステータス=未送信
22:30:07 情報 20.0
22:30:07 情報 処理回数=81,ステータス=未送信
22:30:09 情報 19.0
22:30:09 情報 処理回数=82,ステータス=未送信
22:30:10 情報 18.0
22:30:10 情報 処理回数=83,ステータス=未送信
22:30:11 情報 17.0
22:30:11 情報 処理回数=84,ステータス=未送信
22:30:12 情報 16.0
22:30:12 情報 処理回数=85,ステータス=未送信
22:30:14 情報 15.0
22:30:14 情報 処理回数=86,ステータス=未送信
22:30:15 情報 14.0
22:30:15 情報 処理回数=87,ステータス=未送信
22:30:16 情報 13.0
22:30:16 情報 処理回数=88,ステータス=未送信
22:30:17 情報 12.0
22:30:17 情報 処理回数=89,ステータス=未送信
22:30:20 情報 11.0
22:30:20 情報 処理回数=90,ステータス=未送信
22:30:20 情報 10.0
22:30:20 情報 処理回数=91,ステータス=未送信
22:30:21 情報 9.0
22:30:21 情報 処理回数=92,ステータス=未送信
22:30:22 情報 8.0
22:30:22 情報 処理回数=93,ステータス=未送信
22:30:25 情報 7.0
22:30:25 情報 処理回数=94,ステータス=未送信
22:30:25 情報 6.0
22:30:25 情報 処理回数=95,ステータス=未送信
22:30:26 情報 5.0
22:30:26 情報 処理回数=96,ステータス=未送信
22:30:27 情報 4.0
22:30:27 情報 処理回数=97,ステータス=未送信
22:30:30 情報 3.0
22:30:30 情報 処理回数=98,ステータス=未送信
22:30:30 情報 2.0
22:30:30 情報 処理回数=99,ステータス=未送信
22:30:31 情報 1.0
22:30:31 情報 処理回数=100,ステータス=未送信
22:30:32 情報 0.0
22:30:32 情報 処理回数=101,ステータス=未送信
22:30:35 情報 -1.0
22:30:35 情報 処理回数=102,ステータス=未送信
22:30:37 エラー Exception: Service invoked too many times for one day:
ログを見ると 100回 ではなく、 101回 のようですね。実際のメールを見てみましょう。
やはり101回のようです。
本当に24時間で101回が限度なのか
上の検証で見た通りということで、記事を終わらせてもよかったのですが、当時の状況を思い出しますと、「1通ずつなら送れます!」という現場からの声がありました。その時の私は、24時間前に送信しているものがあり、ちょうど解除された メールがあるという理解でした。
ということで、このテストマクロを再実行します。ちょっと、動きが遅いような感じがします。そして、1通送信されました。これは、どういうことでしょう。念のため、もう1回マクロを実行します。やはり、1通送信されました。
メールも届いています。
つまり、24時間の上限制限もあるが、それとは別に1通は送信できるということでしょうか。
上限の解除は100通目の実行時間からなのか1通ずつなのか
とりあえず、「メール送信マクロは24時間で100通の上限がある」という部分については一旦 認めます。それでは、この上限が解除されるのはいつからなのでしょう。上限に達するまでは、リアルタイムでカウントされているようです(下図)。下の図はマクロで事前にメールを6通送信しておいて、実行した時のものです。
ということで、上限がいつ解除されるのかを確認していきましょう。ここに、24時間と少し前に12通送信し、24時間の間に98通のメールを送信したマクロがあります。
3時間ほど前に実行したところ、「Exception:Service invoked too many times for one day : email.」のエラーが発生しました。なので、まだ24時間の制限は掛かっているようです。
いざ、テスト開始!
期待値としては、マクロ内で12回ループが回ったところで、「Exception:Service invoked too many times for one day : email.」が発生するというものです。ところが、結果は以下のようなものでした。
そうです。いきなり、実行ログに残り99回の表示が出ています。
22:08:53 情報 99.0
これは、マクロの中で上限100回のうちの1回が実行された後に残りの回数を表示しているので、上限がクリアされていたことが分かります。
// createDraftは下書き, sendEmailはメール送信まで
GmailApp.sendEmail(mail_to, subject, body);
//(中略)
spreadsheet.getCurrentCell().setValue('メール送信完了');
Logger.log(MailApp.getRemainingDailyQuota())
結論
「GASで1回のマクロ実行で送信できるのは最大101通である。上限を超えた場合、約24時間は1回のマクロ実行で送信できる回数が1回に制限される。」
実はまだ、制限解除の時間が存在するのか、カウントが蓄積されないインターバルが存在するのか分かっていないのだが、それについては検証する時間がないため、今回はここで決着とする。
また、この記事により、GmailAppとMailAppを両方使えることが分かり、記事化することができました。ここに感謝の意を示します。
なお、他に情報をお持ちの方がいらっしゃいましたら、ぜひともコメントにて教えて頂けると助かります。