見出し画像

コードが読めなくてもできる! 毎朝メンション付きでGoogleカレンダーの予定を流してくれるslackbotの作り方

2020/02/25さらに追記:下記にしばらく取り組めなさそうだったので、とりあえず、スクリプトエディタのメニューの「実行」→「ChromeV8を搭載した新しいApps Scriptランタイムを有効にする」にしたところ、エラーが出なくなりました。

2020/02/13追記:GASの仕様変更により、予定の入っていない日はエラーが出るようになってしまったようです。親切なフォロワーさんがtry catch構文使うとよさそうと教えてくれたので、これを機にJavaScriptちょっと勉強して修正できたらと思ってます。もし上記構文での書き直し方がわかる方いたら、ぜひコメント等で教えていただけると嬉しいです……!


背景

最近、進行管理のお仕事をしてみることになりました。締切等のスケジュールを、最初は手動で、slackのチャンネル上に個人メンションを付けてリマインドしていたのですが、これってbotにやってもらうことができるのでは?と思い、調べてやってみることにしました。この文章の最後にコードと完成イメージも置いておきます。


参照記事

以下の3記事を参照しながらやっていきます。全体のコードはほぼ①そのままです。ありがとうございます🙏
https://designmemo.jp/creative/bot-googlecalendar-slack.html
② (①の参照元) https://qiita.com/seya128/items/028274fc014af37f7931#%E6%A6%82%E8%A6%81
http://whatsweb.info/?p=611

実践

まず、を参照して、手順に従ってどんどん進めていきます。「2-3.コードをコピー&ペーストして編集」の1)までたどり着いたら、メンションを飛ばしたい場合に必要な文を、以下の通り書き足します(参照)。

16行目の下にもう1行追加(エンターキー押せばできます)して、
"LinkNames": 1,
と書きます。

画像1

こんな感じ。

書き足したら、の記事に戻り、2-3の2)以降を行って、自分用のコードに書き換えていきます。
(追加したカレンダーのIDも、各カレンダーの「設定と共有」から取得できます。)
このとき、メンションを入れたい位置に
<@メンバーID|ユーザー名>
と記入します。(参照)

メンバーIDは、他人のものであれば、
slackでアイコンをクリックしプロフィールを表示する→その他→メンバーIDをコピー
自分のものであれば、
ワークスペース名の下にある自分の名前をクリック→プロフィール&アカウント→その他→メンバーIDをコピー
で取得できます。

わたしの場合、メンションを文章の1行目に入れておきたかったので、「c.メッセージの本文」の最初に書きました。
\nはおそらく改行を表しているようです。
ということは、1行目をメンションのみにしたい場合は
<@メンバーID|ユーザー名>\n
としてから2行目以降の文を書くのがよさそうです。

追記:特定の個人以外に、@channel・@hereのメンションも飛ばせます。その場合、<@メンバーID|ユーザー名>の代わりに、<!channel>,<!here>と記入します。

書けたらまたの記事に戻り、2-4以降を行います。
おそらく問題なく動くはずです。

(※スマホアプリから見ても、アイコンと名前をここで書いた通りにするためには、AppディレクトリのIncoming Webhooksにおける名前・アイコンカスタマイズで同様の画像・絵文字・名前に設定することが必要なようです。)

完成

以下、作成したslackbotのコードです(一部伏字に変更済)。

function myFunction() {
  
  var list = "";
  var s;

  s = listupEvent("XXXXXX@gmail.com"); // a.GoogleカレンダーのID
  if (s != "")  list += "\n■今日はどんな日?\n" + s; // b.メッセージの見出し

  Logger.log(list);

  if (list != "") {
    var payload = {
      "text" : "<@メンバーID|ハルカ>\n締切が近いものをお知らせします。\n" + list, // c.メッセージの本文
      "channel" : "#calendar", // d.チャンネルの指定
      "icon_emoji" : ":clipboard:", // e.アイコン画像
      "username" : "スケジュール", // f.Botの名前
      "LinkNames": 1,
    }

    postSlack(payload);
  }
}

function listupEvent(cal_id)
{
  var list = "";
  var cal = CalendarApp.getCalendarById(cal_id);
  var events = cal.getEventsForDay(new Date());
  for(var i=0; i < events.length; i++){
    s = "";
    if (events[i].isAllDayEvent()) {
      s += Utilities.formatDate(events[i].getStartTime(),"GMT+0900","MM/dd  ");
    } else {
      s += Utilities.formatDate(events[i].getStartTime(),"GMT+0900","MM/dd HH:mm");
      s += Utilities.formatDate(events[i].getEndTime(), "GMT+0900","-HH:mm  ");
    }
    s += events[i].getTitle();
    Logger.log(s);

    list += s + "\n";
  }

  return list;
}

function postSlack(payload)
{
  var options = {
    "method" : "POST",
    "payload" : JSON.stringify(payload)
  }

  var url = "https://XXXXXX"; // g. Webhook URL
  var response = UrlFetchApp.fetch(url, options);
  var content = response.getContentText("UTF-8");

}

完成イメージです。
終日の予定と時間ごとの予定はこんな感じで表示されます。

画像2

わたしはアイコンを絵文字の:clipboard:に設定してみました。絵文字の表記についてはこちらを見るとわかります。

主に締切が近いことをお知らせしてもらうつもりなので、こういう文言に変更しましたが、毎日のスケジュールを流したい、みたいな方はに忠実にやるとよいのではないでしょうか。

は複数カレンダーをリストにして流せるコードです。今回は使いませんでしたが、今後管理する案件が増えたら使う可能性があるので、また自分用のワークスペースなどで試してみたいと思います。

おわりに

というわけで、コードの読み方がほぼ一切わからないまま、ここまでできてしまいました。先人が書き残してくれたおかげです。ありがたい。

しかし、コードが書けたり読めたりすると、応用もできてかなり便利そうということがよくわかりました。今後のためにも、今回自分がやったことは一体なんなのか、勉強してみたいと思います。

もっとこうするとよいよ、などありましたら、教えてくださると嬉しいです🙋

読んでくださってありがとうございます!サポートいただけたら、勉強と休憩のために使います。