【GAS小ネタ】メール送信APIを最大限しゃぶり尽くす、3つの小技

::: note
この記事はGoogle Apps Script Advent Calendar 2021の1日目の記事です
:::

https://qiita.com/advent-calendar/2021/google-apps-script

---------------------

## この記事を書いた理由

Google Form + Google App Scriptで予約フォームを運用しました。
無料枠の中で、最大限メール送信APIを使うために工夫をしたので共有します。

## ①メール送信はtry-catchで囲む

メール送信は、さまざまな要因でエラーが起こることがあります。
整理番号配布プログラムや、スプレッドシートに書き込み等も行っている場合、メール送信部分でエラーが起きてプログラムが止まるのは避けたいところ。特に、メール送信上限を超えると`MailApp`も`GmailApp`も例外を投げてきます。

下記のように、例外を拾うと幸せです。

```javascript
    try {
        MailApp.sendEmail(mailAdress, "予約番号送付", "受付番号は" + number + "です。", {
        name: "実行委員会",
        });
    }
    catch (e) {
        console.error(e);
        //なんか処理
    }
    //エラー検知して処理する（スプレッドシートに記録しとくとか）
```

これを行うことで、最悪の場合でも受付番号を後から送付するなどの対応ができます。
私はスプレッドシートの名簿に、メール送信が成功したか失敗したかを一緒に書くようにしました。


## ②Draftに一旦保存することで(GASの範囲では)無制限に送信可能

現在、GAS上でメール送信を行う`GmailApp.sendEmail`メゾット、`MailApp.sendEmail`メゾットは、無料アカウントで100通/1日の制限があります。
ちなみに筆者はこの制限を知らず、大事な場面に運用したためトラウマ級の災害が起こりました。

下記記事によると、下書きを経由するとこの制限を突破できます。

https://zenn.dev/tatsuya_okzk/articles/259203cc416328

しかし、`MailApp.getRemainingDailyQuota`メゾットで取得できるのは、送信残数のみです。実際のところ、何件まで行けるのか調査してみました。

ループで回すと別の制限にかかりそうなので、下記プログラムを使用し、1秒に1通送信してみます。
GASの実行時間制限が6分なので、何度か実行して検証しました。

```javascript
function sendMail(i) {
  try {
    var draft = GmailApp.createDraft(
      "捨てメアド",
      i + "回目テストメール",
      i + "回目テストメールの本文",
      {
        name: "テスト太郎"
      });
    var draftID = draft.getId();
    GmailApp.getDraft(draftID).send();
  } catch (e) {
    console.error(i + "回目のメール送信に失敗しました。")
    console.error(e)
  }
  console.log("メール送信残数 : " + MailApp.getRemainingDailyQuota())
  console.log("-------------------------------")
}

function main() {
  i = 1; //2回目以降は終わったとこまでの数を入力
  while (true) {
    sendMail(i);
    Utilities.sleep(100);
    i++;
  }
}
```
GASにはsleep関数あって助かりました。JSにはないんですよね…

結果はこのようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623593/a7731441-3012-4022-e71f-34bef1394a7e.png)

これは、Gmailそのものの送信制限に引っかかったようです。
GASではなく、普通にメールを送信すると、下記メールが返ってきて送信ができません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623593/2e51fcc7-ff6d-34e0-b379-a01dd73fc609.png)

GoogleのFAQを見ると、500件が上限と書かれています。

> 1 通のメールを合計 500 件を超える宛先に送信したり、1 日に 500 通を超えるメールを送信した場合は、このメッセージが表示されます。

https://support.google.com/mail/answer/22839?hl=ja

しかし、みて分かる通り1000件は送信できていますね
また、1時間ではなく15分後となっています。次章で触れますが、Googleの制限はちょっと曖昧なところが多いです。
ただ、目安としてGAS自体の制限は検証できる限り突破していることが分かると思います。

ちなみに、15分後に再度送ろうとしても送れませんでした。普段使い用のメアドだったため、日常生活に支障が出ました。

## ③送信制限は24時間なのか1日なのか曖昧なことに留意する

無料サービスを使わせていただいている以上、仕方ないことですがメール送信上限の復活のタイミングはあやふやです。
下記のGmail送信上限は、24時間と書かれていますが、GASに関わらず全てのメール送信上限です。

https://support.google.com/a/answer/166852?hl=ja

> Google Apps Script を使用している場合、割り当てが異なる場合があります。

と書かれている通り、GASでは異なるタイミングが適用されるようです。下記GASのリファレンスでは、100件/1日と書かれています。

https://developers.google.com/apps-script/guides/services/quotas

この"1日"が1日を表すのか、24時間を表すかがあやふやなのです。
実際に運用(下書き経由ではなく、直接`MailApp.sendEmail`で送信し、毎回`MailApp.getRemainingDailyQuota`で確認しました。
すると、確かに送信した24時間後にその件数分復活していました。しかし、毎日夕方ごろに100件まで復活している事象が必ず起こりました。
100件まで全回復する時間は未定だったため、仕様がよくわからないところではあります。

## 終わりに

GASは本格運用しないほうがいいなと思っていたのですが、しっかりと仕様を把握すれば便利に使えると感じました。
それでは、楽しいGASライフを！