【効率化】gmailをGoogleSpreadSheetから自動送信する仕組み【働き方改革】

# 概要
googleのサービスを使っています。例えば、メールサービスのgmail。
メールの送信を自動化できないかと思い至る。

業務改善！効率化！！働き方改革！！！
今回は、所定の日時になったらメール送信。

##### gmailで予約送信機能は実装されている
「gmail 予約送信」で検索すると山ほど出てきます。
この予約送信機能を使ってみたけど、１通１通に設定していくのです。
ワンショットのメールを予約送信する分には便利でした。

##### 私の場合、似たようなメールを定期的に送信したい
googleスプレッドシートにて、

* 何通もの予約メールをいっぺんに編集！
* 「えいや！」と宛先、題名、本文、送信予定日時をコピペで貼り付け
* とにかく、ワサっとコピペをしたい

こんな、メール自動送信の仕組みが出来ればなぁ…
そんな感じで、
googleスプレッドでgmail自動送信を実現しました。

- - -

# 先駆者たち
先駆者の諸先輩方が居られます。
ありがとうございます！
丸パクリさせて頂きました！！感謝！！！

Google Apps Scriptで指定時刻にメールを送信するシステムを作ってみた
https://qiita.com/KentoDodo/items/4839af8700742a646cea

Google Apps Scriptで自動でメールを送信する
https://www.kabegiwablog.com/entry/2017/08/23/141037

- - -

# ざっくり手順
基本、先駆者様の記載を参照すれば出来ちゃいますが、
ざっくり手順をまとめておきます。

1. googleアカウントを作成（すでに持っている人はOK）
1. googleスプレッドシートを１つ作成（私は名称を「AutoMailSender」としました）
1. googleスプレッドシートから「google app script」を作成する
1. ソースコードは [ソースコード](#ソースコード) を参照
1. 自動実行したいのでトリガを設定する

# ソースコード
``` *.js
function calledByCron() {
  const COL_NO_TO       = 0;  // to(宛先)列
  const COL_TITLE       = 1;  // title(メールのタイトル)列
  const COL_DESCRIPTION = 2;  // description(メール本文)列
  const COL_SEND_MAIL   = 3;  // send_mail(送信予定日時)列
  const COL_SENT_MAIL   = 4;  // sent_mail(送信完了日時)列
  const COL_STOP_FLAG   = 5;  // stop_flag(送信抑止フラグ)列

  // 現在時刻を取得
  var dtLimit = new Date();

  // 開始行数
  const START_ROWS = 2;  // 2行目から
  // 開始列数
  const START_COLS = 1;  // A列から

  // シートの取得
  var sheet = SpreadsheetApp.getActiveSheet();

  // シートのデータを取得（2次元配列）
  var sheetData = sheet.getSheetValues(START_ROWS, START_COLS, sheet.getLastRow(), sheet.getLastColumn());

  // シートの各行ごとにデータを取り出す
  sheetData.forEach(
    function(value, index)
    {
      // stop_flag値が空文字なら実行
      if ( value[COL_STOP_FLAG] == "" )
      {
        // 送信完了していない
        if ( !value[COL_SENT_MAIL] )
        {
          // 送信予定日時が現在時刻より前ならば、メールを送信する
          if ( (new Date(value[COL_SEND_MAIL])).getTime() < dtLimit.getTime())
          {
            // メールを送信する
            MailApp.sendEmail(value[COL_NO_TO], value[COL_TITLE], value[COL_DESCRIPTION]);
            // 送信完了日時をシートに書く
            sheet.getRange( (START_ROWS + index), (COL_SENT_MAIL + 1)).setValue(dtLimit);
          }
        }
      }
    }
  );

  // memo :
  //   getRange(row, column [, numrows [, numcolumns]])
  //     row        [int] 指定する範囲の行番号。
  //     column     [int] 指定する範囲の列番号。A列を1とする。
  //     numrows    [int] (省略可)範囲の行数を指定する。デフォルト1。
  //     numcolumns [int] (省略可)列数を指定する。デフォルト1。
}
```

- - -

# 自動実行の設定
最後に自動実行の設定ですが、
一応、先駆者様の記事を見て頂くと分かりますが、
googleさんのユーザーインターフェースはコロコロ変わるので、
画像が少し古かったりします。なので、キャプチャ撮り直し（2019/06/05）ました。

- - -

(1) google app scriptの画面上で、以下画像の赤枠をクリック
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133593/7b293331-a4ce-85fd-6a80-c51dce779f3b.jpeg)

- - -

(2) 新しいタブ画面（使用ブラウザ：Chrome）が開く

* G Suite Developer Hub なる画面が開きます
* 以下画像のように、「(googleスプレッド名) > トリガー」が開く

- - -

(3) 右下の「トリガーを追加」をクリック
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133593/bdf16efa-df04-2f39-c849-2a8934646124.jpeg)

- - -

(4) トリガーの追加ダイアログ画面が表示されるので適当に設定して保存する
![キャプチャ3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133593/3f58e8ee-d1c7-a076-3784-08098d366416.jpeg)

- - -
# ひとつだけ機能追加
私の場合、先駆者様のソースから１つだけ機能を追加しています。
「stop_flag」列を作っておいて、
その列に何がしかの値（例えば「1」）が入っている場合は、
送信日時に達していてもメール送信しない。という機能です。
ひとまずコピペでメールの雛形をたくさん作っておいて、
後でちょこちょこと本文を弄るのですが、
作業を中断してそのまま忘れ去ってしまって、
事故的に誤爆メールが飛ぶのを防ぐためです。
内容を確認したら、stop_flagのセルの値を「空文字」にする。
という運用をしています。
ちなみに、to列には宛先アドレスを設定しますが、
複数人に送信する場合は、カンマ「,」区切りでセルに設定しておきます。