フューチャー夏休み自由研究連載11本目の記事です
はじめに
こんにちは。TIGメディアユニットの仁木です。Slackに投稿するための日報をBOT化・自動化したので自由研究企画に混ぜてもらい記事にすることにしました。毎日共通で書かなければいけないタイトルなどの固定項目やスケジュールの記載を自動化することで、作成時間を短縮し、重要な部分に時間を割けるようになりました。

概要
Googleスプレットシート及びGoogleカレンダーの情報を利用して、日報として整形するスクリプトをスプレットシートのスクリプト機能を利用して書いた後、SlackのIncoming WebhookのURLにリクエストを送信します。

準備
今回利用するサービスについて説明します。
Slackのアプリ 「Incoming Webhook」
SlackのIncoming Webhookというアプリを利用しました。

どのチャンネルやダイレクトメールにBOTを利用するかを決定すると、Webhook URLが発行されるので、このURLに対してPOSTリクエストを送ります。URLが発行されるページに例が詳しく載っているので何かしらの形でPOSTリクエストを送ったことがある人なら簡単に使えると思います!
Googleスプレットシート
スプシと略して呼んでいたら上司が「スプシって略すのか..」と関心していました。Googleアカウントがあれば誰でも無料で使える表計算シートです。今回はスクリプトエディタ機能でスプレットシートに書いた情報を利用してSlackのWebhookURLへPOSTリクエストを送ります。

Google Apps Script (GAS)
Googleスプレットシートのスクリプトエディタ機能を利用して、スクリプトを書いていきます。書いたスクリプトはボタンひとつで簡単に実行でき、さらにトリガーで実行時間を指定する機能も備わっており、設定するだけで決まった時間にPOSTリクエストが実行できます。

スクリプトの作成
今回は特に、固定項目追加・スケジュールの追加について解説します。細かく見ると休日判定もしていますが、シンプルにまとめているページが他にいくつかあったので、今回は省略しています。
固定項目の自動追加
まずは、Googleスプレットシートにタイトルなど毎日の日報で固定化されている情報をあらかじめ記載しておき、その情報を使ってテンプレを作成していきます。ここまででも、項目を打ち込むルーティーンをなくすことができ、作成時間を多少減らすことができそうです。作成したスプレットシートとコードを以下に記載します。

スプレットシートの情報をスクリプトで抽出します(全体のコードは後述)
 let sheet = SpreadsheetApp.getActiveSheet(); let message = "日報 \n";
  for(let i = 2; i<= sheet.getLastRow(); i++) {   let subtitle = sheet.getRange(i, 1).getValue();   let defmessage = sheet.getRange(i, 2).getValue();   let option = sheet.getRange(i, 3).getValue();      message += "■"+subtitle+"\n";      if(defmessage!==""){     let msgs = defmessage.split("\n");     let cnt = 0;     for(const msg of msgs) {       if(cnt===0) message += INDENT+msg+"\n";       else message += SECOND_INDENT+msg+"\n";       cnt++;     }   }      if(option!=="") {     if(option===OPTION_GET_TODAY_CAL) message += addTodayCal();     else message += addTomorrowCal();   } }
 
  | 
 
スケジュールの自動追加
さらに作成時間を減らしたいので、今日明日のスケジュールをカレンダーから抽出して固定項目の中を埋めていきます。以下の関数を利用してスケジュールを取得します。予定のステータスを確認して、自分が主宰の予定及び、参加・未定と回答した予定のみを取得しています(全体のコードは後述)
  const JAP_HOLIDAY_CAL_ID = 'ja.japanese#holiday@group.v.calendar.google.com';
  const MY_CAL_ID = 'piyopiyoPPP@example.com';
 
 
 
 
 
 
  function addTodayCal() {   let todayCal = CalendarApp.getCalendarById(MY_CAL_ID);   let today = new Date();   const events = todayCal.getEventsForDay(today);   let message = "";   for(const event of events) {          if(event.getMyStatus()==="YES" ||event.getMyStatus()==="OWNER" || event.getMyStatus()==="MAYBE") {       message += INDENT+event.getTitle()+"\n";     }   }   return message; }
 
 
 
 
 
  function addTomorrowCal() {   let tomorrowCal = CalendarApp.getCalendarById(MY_CAL_ID);   let tomorrow = new Date();   tomorrow.setDate(tomorrow.getDate()+1);   const events = tomorrowCal.getEventsForDay(tomorrow);   let message = "";   for(const event of events) {          if(event.getMyStatus()==="YES" ||event.getMyStatus()==="OWNER" || event.getMyStatus()==="MAYBE") {       message += INDENT+event.getTitle()+"\n";     }   }   return message; }
 
  | 
 
BOT化
コード
全体のコードです。スプレットシートを作った後、ツールからスクリプトエディタを開いてコードをコピーし、【STEP 1】,【STEP 2】を設定すると動くようにしています。気になった方はぜひ動かしてみてください!
コードを見る
 
 
 
 
  const SLACK_WEBHOOK = 'https://piyopiyo';
  const JAP_HOLIDAY_CAL_ID = 'ja.japanese#holiday@group.v.calendar.google.com';
  const MY_CAL_ID = 'piyopiyoPPP@example.com';
  const OPTION_GET_TODAY_CAL = 'get_today_cal'; const OPTION_GET_TOMORROW_CAL = 'get_tomorrow_cal';
  const INDENT = '    ・'; const SECOND_INDENT = '      ';
 
 
 
  function createNippo() {   let today = new Date();   if(isHoliday(today)) return;
    let url = SLACK_WEBHOOK;      let sheet = SpreadsheetApp.getActiveSheet();   let message = "日報 \n";      for(let i = 2; i<= sheet.getLastRow(); i++) {     let subtitle = sheet.getRange(i, 1).getValue();     let defmessage = sheet.getRange(i, 2).getValue();     let option = sheet.getRange(i, 3).getValue();          message += "■"+subtitle+"\n";          if(defmessage!==""){       let msgs = defmessage.split("\n");       let cnt = 0;       for(const msg of msgs) {         if(cnt===0) message += INDENT+msg+"\n";         else message += SECOND_INDENT+msg+"\n";         cnt++;       }     }          if(option!=="") {       if(option===OPTION_GET_TODAY_CAL) message += addTodayCal();       else message += addTomorrowCal();     }   }
       Logger.log(message);   let options = createOptions(today, message);   UrlFetchApp.fetch(url,options); }
 
 
 
 
 
 
  function isHoliday(date) {      if(date.getDay()===0 || date.getDay()===6) return true;
       let holidayCal = CalendarApp.getCalendarById(JAP_HOLIDAY_CAL_ID);   return (holidayCal.getEventsForDay(date).length>0); }
 
 
 
 
 
 
 
  function createOptions(date, message) {   const date_format = 'yyyy/MM/dd'   let fdate = Utilities.formatDate(date, 'Asia/Tokyo', date_format);   let json_data ={"username":"日報"+fdate,     "text": message,     "icon_emoji": ":slack:"}
    let payload = JSON.stringify(json_data);   let options = {     "method": "post",     "contentType": "application/json",     "payload" : payload   };   return options; }
 
 
 
 
 
  function addTodayCal() {   let todayCal = CalendarApp.getCalendarById(MY_CAL_ID);   let today = new Date();   const events = todayCal.getEventsForDay(today);   let message = "";   for(const event of events) {          if(event.getMyStatus()==="YES" ||event.getMyStatus()==="OWNER" || event.getMyStatus()==="MAYBE") {       message += INDENT+event.getTitle()+"\n";     }   }   return message; }
 
 
 
 
 
  function addTomorrowCal() {   let tomorrowCal = CalendarApp.getCalendarById(MY_CAL_ID);   let tomorrow = new Date();   tomorrow.setDate(tomorrow.getDate()+1);   const events = tomorrowCal.getEventsForDay(tomorrow);   let message = "";   for(const event of events) {          if(event.getMyStatus()==="YES" ||event.getMyStatus()==="OWNER" || event.getMyStatus()==="MAYBE") {       message += INDENT+event.getTitle()+"\n";     }   }   return message; }
 
  | 
 
  
まとめ
Slack×GASを利用した日報テンプレートBOTを作成しました。日々のタスクの自動化・整理の参考になれば嬉しいです。
余談ですが、Slackは投稿するときにアイコンがスタンプから選べるのが可愛いです。Google ChatのBOTを作った時は、アイコン画像のurlを作るのに苦労したので気軽に可愛いアイコンが付けられるのはそれだけでテンションが上がりました!