見出し画像

有料記事はこんな内容にします

まとめてレシピ集!みたいに販売したかったけど欲しい情報とそうじゃない情報があるので個別に販売します

値段について

流石に1000円とかそんな値段では無いです
基本的に500円以下に抑えます
ただかなりボリュームのあるコードだと超えてしまうかもしれません
どうしても無料で習得したいという方はご自身で調べるなどをお願いします

サンプル

ここから有料記事の内容をそのまま最後まで書いてみます
購入の判断をこれでお願いします
また僕のマガジンに掲載しているGASの基礎をやっていることを前提に進めます
自画自賛で申し訳ないのですがかなりわかりやすいと思ってます

作るもの

会社の明日の予定を社員に通達するツール

仕様

決まった時間帯に明日の予定を取得してメール送信
予定がない場合は送信しない
送信相手はシートに記載

また予定の開始時刻、終了時刻の記載の無い「終日予定」の場合は時刻の記載はしない
送信内容はこのような感じ

処理の流れ

  1. カレンダー操作に必要な情報を取得する

    1. カレンダーID

    2. 今日の日付

    3. 明日の日付

    4. 予定一覧

  2. 予定がある場合は情報を受取メールを送る

  3. 本文を格納する変数を用意

  4. 予定の各情報を取得

    1. 予定のタイトル

    2. 予定の開始時刻

    3. 予定の終了時刻

    4. 予定の場所

    5. 予定の説明

  5. 取得した情報を元にメールする内容に当てはめる

  6. メールを送信

    1. シートの指定

    2. リストが何行まであるかを調べる

    3. リストの数だけ送信する

  7. トリガーの設定

実装

上の処理の順番通り書きていきましょう
まずはスプレッドシートでメールリストの作成とScriptAppからエディタを開きます
リストはこんな感じで大丈夫です

カレンダーの明日の予定になにか適当なものを入れてください

こんな感じで入れてみました

1.カレンダー操作に必要な情報を取得する

今回必要な情報は以下の通りでしたね
カレンダーID、今日の日付、明日の日付、予定一覧
まずはそれを変数に入れていきましょう

  // 必要な情報を揃える

  var calender = CalendarApp.getCalendarById('カレンダーID');
  var today = new Date();
  var tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
  var events = calender.getEventsForDay(tomorrow);

カレンダーIDを見つける場所は覚えていますか?
忘れてしまった方はこちらから

重要なコードはここです

var tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
var events = calender.getEventsForDay(tomorrow);

まずは1行目を見てください

var tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);

変数tomorrowには変数todayで取得した日付に+1日しています

today.getDate() + 1

これで日にちに+1、つまりは明日にしています
続いて2行目

var events = calender.getEventsForDay(tomorrow);

変数eventsには変数calenderで指定されたカレンダーから取得した予定を配列で格納していきます

.getEventsForDay(tomorrow);

これで予定を取得します
(  )はいつの予定を取得するか指定しています
ここに変数todayを入れると今日の予定を取得してきます

2.予定がある場合は情報を受取メールを送る

予定が無いのに空メールが送られてきたら迷惑極まりないですよね
具体的に言うと休みの日なんて会社の予定無いですからメールを送る必要は有りません
その処理を書きます

  // 必要な情報を揃える
  var calender = CalendarApp.getCalendarById('カレンダーID');
  var today = new Date();
  var tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
  var events = calender.getEventsForDay(tomorrow);

  /* ここから追加 */
  // 予定がある場合のみ処理をする
  if (events.length != 0) {
   //ここに処理を書いていく
  }

条件式ですが「!=」は〇〇ではない場合という意味でしたね
ですから今回は変数eventsに入っている値が0ではない場合処理をするということになります
反対に0であれば何もしないということになります

3.本文を格納する変数を用意する

  if (events.length != 0) {
   /* ここから追加 */
    var body = '';
  }

空の変数を用意します
次の項目でeventsの中身の予定タイトルや予定の説明などを取得します
それをどんどん本文に追加していくわけですから初めは空っぽにしておきましょう

4.予定の各情報を取得する

予定タイトル、予定開始時刻、予定終了時刻、予定場所、予定の説明
を取得していきます

  if (events.length != 0) {
    var body = '';

    /* ここから追加 */
    for (var i = 0; i < events.length; i++) {
      var title = events[i].getTitle();
      var startTime = events[i].getStartTime();
      var endTime = events[i].getEndTime();
      var location = events[i].getLocation();
      var description = events[i].getDescription();
    }
  }

まずはfor文の条件式で
変数eventsに要素がある限り繰り返す
ということです
ここは基礎でやりましたね

そして以下5行

var title = events[i].getTitle();
var startTime = events[i].getStartTime();
var endTime = events[i].getEndTime();
var location = events[i].getLocation();
var description = events[i].getDescription();

上から順に予定タイトル、開始時刻、終了時刻、場所、説明
を取得してます
getTitle()などgetを使うことで取得できましたよね
終日予定の場合は
開始時刻は「0:00」終了時刻は「0:00」という形で取得します
必要な情報を取得したのであとはメールを送る準備をします

5.取得した情報を元にメールする内容に当てはめる

それではメール本文を作っていきます
終日予定の場合は開始時刻と終了時刻を表示させないという仕様でしたね
ということはif文で条件分岐してあげる必要があります
条件式から書きましょう

    for (var i = 0; i < events.length; i++) {
      var title = events[i].getTitle();
      var startTime = events[i].getStartTime();
      var endTime = events[i].getEndTime();
      var location = events[i].getLocation();
      var description = events[i].getDescription();

      /* ここから追加 */

      // 開始時間と終了時間が0:00の場合はbodyに含めない
      if (startTime.getHours() !== 0 || startTime.getMinutes() !== 0 || endTime.getHours() !== 0 || endTime.getMinutes() !== 0) {
        
      } else {
       
      }
    }

では条件式を詳しく見ていきましょう

if (startTime.getHours() !== 0 || startTime.getMinutes() !== 0 || endTime.getHours() !== 0 || endTime.getMinutes() !== 0)

この条件式は

・startTImeの時が0ではない場合
・startTImeの分が0ではない場合
・endTimeの時が0ではない場合
・endTimeの分が0ではない場合

どれか一つでも当てはまれば{   }の処理を実行します

開始時刻10:00〜終了時刻0:00までの予定ならstartTImeの時が10、つまり0では無いので処理が実行されます

開始時刻0:00〜終了時刻0:00なら上記の条件すべて当てはまらないので「else」の処理を実行します

では処理を書いていきますまずは条件式に当てはまる場合

// 開始時間と終了時間が0:00の場合はbodyに含めない
if (startTime.getHours() !== 0 || startTime.getMinutes() !== 0 || endTime.getHours() !== 0 || endTime.getMinutes() !== 0) {
  
   /* ここから追加 */
  startTime = Utilities.formatDate(startTime, 'JST', 'HH:mm');
  endTime = Utilities.formatDate(endTime, 'JST', 'HH:mm');
  body = body + `${startTime} ~ ${endTime}${title}】\n ${location}\n ${description}\n\n`;
} else {
       
}

最初の2行目を解説します

startTime = Utilities.formatDate(startTime, 'JST', 'HH:mm');
endTime = Utilities.formatDate(endTime, 'JST', 'HH:mm');

これは時間表示を読みやすくしています
これをしなかった場合はかなり読みづらいです
上がそのまま出力した場合で、下がUtilitesで整えた出力です

Utilities.formatDate(表示したい日時の変数, 'タイムゾーン', '表示形式');

で表します
今回は時間だけなのでHH:mm(時:分)にしています

次にこのコード

body = body + `${startTime} ~ ${endTime}${title}】\n ${location}\n ${description}\n\n`;

本文として送る内容を入れていきます
bodyにどんどん情報を追加していきたいのでこの書き方をします

明日の予定が「会議」「面談」の2つだとしましょう

まず変数bodyにbody+会議の情報(開始時刻とか説明とか)を入れます
このときbodyは空なのでbody+は無意味です

次にbodyに面談の予定情報を入れます
このときにbody(会議の予定情報が入っている)+面談の情報になります
このように予定の情報を追加して行きます

次は開始時刻と終了時刻が0:00のときのコード

if (startTime.getHours() !== 0 || startTime.getMinutes() !== 0 || endTime.getHours() !== 0 || endTime.getMinutes() !== 0) {
   startTime = Utilities.formatDate(startTime, 'JST', 'HH:mm');
   endTime = Utilities.formatDate(endTime, 'JST', 'HH:mm');
   body = body + `${startTime} ~ ${endTime}${title}】\n ${location}\n ${description}\n\n`;
} else {
  /* ここから追加 */
   body = body + `【${title}】\n ${location}\n ${description}\n\n`;
}

開始時刻と終了時刻は表示したくないので変数startTimeとendTimeを抜いています

6.メールを送信する

メールを送るには送信先のアドレスを指定してないといけません
今回はシートに書かれたリストから受け取ります
すると必要な情報として
リストの書かれたシート、リストが何行まであるか、リストのメールアドレス
この3つが必要ですね

    // イベントの各情報を取得する
    for (var i = 0; i < events.length; i++) {
      var title = events[i].getTitle();
      var startTime = events[i].getStartTime();
      var endTime = events[i].getEndTime();
      var location = events[i].getLocation();
      var description = events[i].getDescription();

      // 開始時間と終了時間が0:00の場合はbodyに含めない
      if (startTime.getHours() !== 0 || startTime.getMinutes() !== 0 || endTime.getHours() !== 0 || endTime.getMinutes() !== 0) {
        startTime = Utilities.formatDate(startTime, 'JST', 'HH:mm');
        endTime = Utilities.formatDate(endTime, 'JST', 'HH:mm');
        body = body + `${startTime} ~ ${endTime}${title}】\n ${location}\n ${description}\n\n`;
      } else {
        body = body + `【${title}】\n ${location}\n ${description}\n\n`;
      }
    }

    
    /* ここから追加 */
    // メールの送信
    var sheet = SpreadsheetApp.getActiveSheet();
    var row = sheet.getLastRow();
    for (var i = 2; i <= row; i++) {
      var to = sheet.getRange(i, 2).getValue();
      GmailApp.createDraft(to, '明日の予定', body);
    }

まずはメールアドレスが書いてあるシートを選択します

var sheet = SpreadsheetApp.getActiveSheet();

.getActiveSheet();で現在開いているスプレッドシートのシートを指定してくれます
今回はシートは1つしか無いのでこれで大丈夫です
次にこのコード

var row = sheet.getLastRow();

これでメールアドレスがシートの何行まで書かれているかを取得します
これは次の繰り返し文で使用します

    for (var i = 2; i <= row; i++) {
      var to = sheet.getRange(i, 2).getValue();
      GmailApp.createDraft(to, '明日の予定', body);
    }

繰り返しの条件式は
メールアドレスの記載は2行目からなのでiは2です
先程取得したメールアドレスが記載されている最終行までを繰り返します

var to = sheet.getRange(i, 2).getValue();

ここでメールアドレスを取得しています
1回目の繰り返しの処理の場合はセル2行目の2列目を取得という事
つまりはリストの一番上です

 GmailApp.createDraft(to, '明日の予定', body);

取得したメールアドレスに送信します
今回は送信ではなく下書きです

 GmailApp.createDraft(送信先アドレス, 件名, 本文, オプション);

で下書きの処理が出来ます
今回はオプションは無しですから書いていません

一回実行してみましょう
実行してGmailを確認します

開いてみて

こんな感じになっていたらOKです

7.全体コードを確認

最後に全体コードを確認しておきましょう

function myFunction() {
  // 必要な情報を揃える
  var calender = CalendarApp.getCalendarById('カレンダーID');

  var today = new Date();
  var tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
  var events = calender.getEventsForDay(tomorrow);


  // イベントが存在しない場合はメールを送信しない
  if (events.length != 0) {
    var body = '';

    // イベントの各情報を取得する
    for (var i = 0; i < events.length; i++) {
      var title = events[i].getTitle();
      var startTime = events[i].getStartTime();
      var endTime = events[i].getEndTime();
      var location = events[i].getLocation();
      var description = events[i].getDescription();

      // 開始時間と終了時間が0:00の場合はbodyに含めない
      if (startTime.getHours() !== 0 || startTime.getMinutes() !== 0 || endTime.getHours() !== 0 || endTime.getMinutes() !== 0) {
        startTime = Utilities.formatDate(startTime, 'JST', 'HH:mm');
        endTime = Utilities.formatDate(endTime, 'JST', 'HH:mm');
        body = body + `${startTime} ~ ${endTime}${title}】\n ${location}\n ${description}\n\n`;
      } else {
        body = body + `【${title}】\n ${location}\n ${description}\n\n`;
      }
    }

    // メールの送信
    var sheet = SpreadsheetApp.getActiveSheet();
    var row = sheet.getLastRow();
    for (var i = 2; i <= row; i++) {
      var to = sheet.getRange(i, 2).getValue();
      GmailApp.createDraft(to, '明日の予定', body);
    }
  }

}

8.トリガーの設定

最後にどのタイミングで処理を実行するか決めましょう
僕は午後8時〜9時の間にしてみましょうか
やり方は覚えていますか?

を参考にやってみましょう!

おわりに

お疲れ様でした
実際の業務に使えるツールが完成しましたね
以上がサンプルの有料記事になります
このくらいのボリュームだと200〜300円を想定しています
僕も生活があるので無償でというわけにはいかなくて・・・。
申し訳ございませんがご了承ください

こういうツールの作り方教えてほしい!などありましたらコメントください
TwitterAPIを使った自動ツールなども作れますが最近Twitterの規約が厳しくなったので使い勝手は悪いので悩んでます
下手な使い方するとアカウント停止になりますし

この記事が気に入ったらサポートをしてみませんか?