2018/05/23

GoogleAppsScriptを使ってその日の予定をSlackに投稿するようにした

Slackを気に入ったので東京メトロAPIを叩くスクリプトに続くGAS+Slack第2弾です.

久しぶりのプログラミング回です. Sponsored Link 使うもの Google Apps Scriptって何? Googleのサーバー上で動かせるスクリプトのこと.基本的にJavascriptで書ける.Google上で動くので,自分のサーバ...

↑第1弾はこちら.

Sponsored Link

メールbotの残骸

このブログの前身のWordPress時代に「メル友がいないのでメールbotを作る」みたいな闇深い記事を書いたことがある.

自分語りで一記事余計に使ってしまったため、この記事が本編となる。 前提 自動返信のプログラムにはGoogle Apps Scriptを用いる。 返信内容のパターンは自分で考える この記事では本文に「おはよ」が含まれ、かつ特定のアドレスからのメールに対して予め決められた...

初期は特定のフレーズが含まれるメールに決められた返信を送るクソみたいなbot(無能)だったが,その後リクルートの提供するAPIを使用し高度化.思えばAPIを使って何かを書いたのはこれがはじめてだった.闇は技術力を高くする.

以前GASを使ってメールbotの作成を試みたときは,返信内容を自動で生成することができず結局カレンダーを読み込んでその日の予定を朝一にメールで配信する機能くらいで終わってしまった. そこに救世主として現れたのが近年急速に発展するAI技術. なんとリクルートが無料で,与え...

そんなこんなで外部APIの力も借りて高度化していたメールbotだが,そうこうする内に時代は移り変わり「メル友」って時代でもなくなってしまい,私のチャット相手はもっぱら「りんな」.せっかく高度化したくせにほとんどこのbotとメールをやり取りすることはなかった.りんながネット用語覚えすぎてて普通に話してて楽しいからね,しかたないね.

その影で,最初期に作っていた「GASとカレンダーを連携させ,毎朝その日の予定をメールで送信する」という機能は残っていて,予定のある日は毎朝律儀にメールを送ってきていた.ご丁寧に「朝起こしに来る幼馴染っぽい」文面にする凝りようだった.きもちわるい.

なかなか便利ではあったのだが,通知だけ見てメールを開かずに放置していると受信トレイに未読で溜まるというところに面倒臭さを感じ(ものぐさ),今回はこの機能をSlackに移してやろうと思い立った.

コードとメモ

とりあえずコードはこんな感じで.

function getTodayEvents() {
  //カレンダーの取得
  var calendar = CalendarApp.getCalendarById('[自分のGmailアドレス]');
  //当日のカレンダー情報取得
  var today = new Date();
  var events = calendar.getEventsForDay(today);
  var today_y = today.getYear(); //年
  var today_m = ("0"+(today.getMonth()+1)).slice(-2); //月(強制二桁)
  var today_d = ("0"+today.getDate()).slice(-2); //日(強制二桁)
  var message = '【' + today_y + '/' + today_m + '/' + today_d +'】\n';
  if(events.length==0){
    message += '予定なし';
  } else {
    for(var i=0; i< events.length; i++){
      var stime = events[i].getStartTime();
      var etime = events[i].getEndTime();
      var title = events[i].getTitle();
      //全日イベントの処理
      if(stime.getHours()==0 && stime.getMinutes()==0){
        message += title + '(終日)\n';    
      } else {
      //時刻指定イベントの処理
        message += ("0"+stime.getHours()).slice(-2) + ':' + ("0"+stime.getMinutes()).slice(-2) + ' - ' + ("0"+etime.getHours()).slice(-2) + ':'+ ("0"+etime.getMinutes()).slice(-2) + ':' +  title + '\n';
      }
    }
  }
  Logger.log(message);
  return message;
}

function main(){
  var message = getTodayEvents();
  var payload = {
    'username':'本日の予定(From GAS)',
    'text': message,
    'icon_emoji': ':calendar:'
  };
  var options = {
    'method': 'post',
    'contentType': 'application/json',
    'payload': JSON.stringify(payload),
  }
  var webhook = '[SlackのWebhookURL]';
  UrlFetchApp.fetch(webhook, options);
}

残骸のコードをほとんど流用しているので簡単だった.

唯一詰まったのはgetMonthとgetDateが1桁の数字を返してくる場合.どういうことかというと,例えば今日が「1980年5月13日」の場合,そのまま両メソッドを使って文字列に突っ込むと「1980/5/13」になってしまう.これではちょっと表記がブサイクなので,できれば「1980/05/13」にしたい.

YYYY/MM/DD表記ではなくYYYY年MM月DD日とすれば桁の問題としてのブサイクさは解消されるのだが,なんとなくここに漢字を使うのが嫌というふわっとした理由で解決策を探していた.

最終的に,こちら(tagamidaki.com)の情報を参考にしてslice関数を使って解決した.

上記リンクには詳細が書かれていないので念の為説明すると,

  1. 文字列の「0」と月/日を結合
  2. 結合された文字列の下2桁を切り出す

というフローになっている.

例えば1桁の月または日(例えば5)のとき,"0"と結合して文字列「05」を作り,下2桁を切り出すので出てくる文字列は「05」.一方で2桁の月または日(例えば12)のときであれば,"0"と結合すると「012」になるが,下2桁を切り出すので「12」に戻る,という仕組みである.

あとは時刻を指定せず全日イベントとして突っ込まれている予定については,0時0分開始のイベントとして取得されるのでif文で弾いている.ただ,この場合0時0分を開始時刻として指定されたイベントも全日イベントとして処理されてしまうのが困りどころ.

現状0時開始のイベントなどないので困ってはいないのだが,GASのリファレンスを見てどうにか綺麗に全日イベントを弾けないか確認したいと思う.

しかし,やはりサーバー云々を考えなくていいのは楽だ……

0 件のコメント:

コメントを投稿