Typetalk(タイプトーク)

Typetalk で Google カレンダーの予定を確認 〜 お手軽ボットレシピ

仕様や画面は現行バージョンと異なる可能性があります。
Typetalkの最新版についてはこちらからご確認ください。

ヌーラボでは、毎日Typetalkを通して各拠点間のやり取りをしています。

社員同士のやりとりも活発ですが、それに紛れて、自動で動くプログラム「ボット」もTypetalkにたくさんの通知をしています。

弊社のボットの一つ『nubot君』。沢山の機能がありますが、ここでは各地の祭日をお知らせしています。

「ボット」にも様々な種類があって、自動化されたビルドプロセスからの経過報告、話しかけることで出社記録(「ヌーラボ社内の勤怠管理アプリ「Hello Goodbye」の紹介」)など、高度なものもありますが、現在のTypetalkではもっと「気軽なボット」も作りやすくなってます。

今回は、「Googleカレンダーに入っている今日の予定を、毎朝Typetalk 上でお知らせする」ボットレシピを、Google Apps Scriptを使ってご紹介します!(50行程のスクリプトをコピー&ペーストするだけで簡単に作れます)

Google Apps Script はGoogle サービス上で動くプログラミング環境で、Javascriptを使ってGoogleドライブやGmailなどのGoogleの各サービスを操作できます。もちろんGoogleカレンダーの情報を取ってくるのもお手の物です。

「ボット」アカウントを作成してみる

カレンダーから今日の予定を抜き出すのは Google Apps Scriptでできるとして、Typetalkに投稿するにはどうすればいいのでしょうか?

実はこれもすごく簡単で、Typetalkではボットを利用したいトピックに「ボット用アカウント」を追加できます。トピック名の横にある「トピックの編集」から「ボット」のタブを開いてみましょう。「ボットの追加」を押すと登録画面が開きます。

「トピックの編集」の中に「ボット」というタブがあります。

通常のユーザーと同じく、「ID」は英数字でボットのTypetalk ID(ボットと一般のユーザーを区別するために登録後、末尾に「+」が追加されます)、「名前」は投稿時に表示される名前になります。今回 ID は「gcalbot」、名前は「今日の予定お知らせ君」にします。左の画像をクリックするとアイコンが変更できるので、フリー素材のカレンダー画像を設定してみます。

その下には「API スコープ」と「Webhook」がありますが、今回はトピックに投稿する権限があればいいので、「topic.post」にチェックが入っていれば大丈夫です。

アイコン画像、「ID」、「名前」、「API スコープ」で「topic.post」が選択されていればOK。

この状態で下にある「作成」ボタンを押してみましょう。画面が再読み込みされ、さらに下に「Typetalk トークン」「メッセージの取得と投稿のURL」「メッセージの投稿コマンドサンプル」が表示されます。これで「ボット」作成は完了です。

中央の「メッセージの取得と投稿のURL」をメモ帳などにコピーしておきましょう。

新しく出てきた項目の中央「メッセージの取得と投稿のURL」が今回利用するものです。なんと簡単!ここにHTTP POSTをすればメッセージが投稿できてしまいます。右端にあるクリップボードアイコンを押してコピーし、メモ帳などに貼っておきましょう。

利用するカレンダーの「カレンダーID」をコピー

次にお知らせしたい予定が入っているGoogle カレンダーを選びましょう。Google Apps Scriptからカレンダーを指定するためには「カレンダーID」が必要になります。

利用したいカレンダーを選び「カレンダー設定」を開きます。

利用したいカレンダーの「カレンダー設定」を開くと、「カレンダーのアドレス」の末尾に括弧で「カレンダーID」が表示されています。選択してコピーして、これもメモ帳などに貼っておきましょう。

「カレンダーのアドレス」の後ろにある「カレンダーID」を選択してコピーしておきます。

お知らせしたい予定がないと何も出力されないので、今日の予定をいくつか追加しておきましょう。

テスト用の予定をいくつか追加しておきます。

これで「今日の予定の入っている Googleカレンダー」と「Typetalk上でお知らせする」方法が手に入りました。いよいよ Google Apps Scriptで「Googleカレンダーに入っている今日の予定をTypetalk上でお知らせ」してみましょう。

Google Apps Script を作る

Google ドライブを開きます。赤い「新規」ボタンを押して「その他」を選ぶと「Google Apps Script」が追加されていますか? 無い場合は、「アプリを追加」から検索して追加しましょう。

ここでは「新規」「その他」の下に「Google Apps Script」が表示されてますが、ない場合は「アプリを追加」から検索して追加してください。

新規のGoogle Apps Scriptを作成します。まず、一番上の「無題のプロジェクト」をクリックしてお好きな名前をつけてください。今回はTypetalk上の「ボット」の名前に合わせて「今日の予定お知らせ君」にしておきます。

「無題のプロジェクト」の部分がプロジェクト名、「function myFunction()」と書かれている部分がコードを貼り付ける部分です。

「function myFunction()」等書かれた一番広い部分がコードを書く部分です。中身を空にして次のコードを貼り付けましょう。

var calendars = [
  "nulab.co.jp_xxxxxxxxxxxxxxxxxx@resource.calendar.google.com"
];

function remindEvents() {
  CalendarApp.setTimeZone("Asia/Tokyo");
  var today = new Date();
  var messages = ["Today's events\n"];
  for(var i in calendars){
    messages = messages.concat(getEventsFromCalendar(calendars[i], today));
  }
  if(messages.length > 1){
    postToTypetalk(messages);
  }
}

function postToTypetalk(messages){
  var params = {
    method: "POST",
    payload: { message: messages.join("\n") }
  };

  UrlFetchApp.fetch("https://typetalk.in/api/v1/topics/xxx?typetalkToken=XXXXXXXXXXXXX", params);
}

function getEventsFromCalendar(calendarId, eventDate){
  var cal = CalendarApp.getCalendarById(calendarId);
  var messages = [];
  var events = cal.getEvents(getLocalDate(eventDate, 0, 0, 0), getLocalDate(eventDate,23,59,59));
  for(var i in events){
    var e = events[i];
    if(e.isAllDayEvent()){
      messages.push("... " + e.getTitle() + " (All day)");
    }else{
      messages.push("... " + e.getTitle() + " (" + formatTime(e.getStartTime()) + "~" + formatTime(e.getEndTime()) + ")");
    }
  }
  if(messages.length > 0){
    messages.unshift("<<" + cal.getName() + ">>");
  }
  return messages;
}

function getLocalDate(d, hour, min, sec){
  return new Date(d.getYear(), d.getMonth(), d.getDate(), hour, min, sec);
}

function formatTime(d){
  return Utilities.formatDate(d, "Asia/Tokyo", "HH:mm");
}

このコードがやっていることが「Google カレンダーに入っている今日の予定を Typetalk 上でお知らせする」なのですが、大事なのは2行目と23行目の二箇所です。2行目の「nulab.co.jp_xxxxxxxxxxxxxxxxxx@resource.calendar.google.com」が先ほどコピーしておいた「カレンダーID」です。

23行目の「https://typetalk.in/api/v1/topics/xxx?typetalkToken=XXXXXXXXXXXXX」の部分が Typetalk 上でコピーした「メッセージの取得と投稿のURL」です。この二箇所を先ほどコピーしておいた文字列でそれぞれ置き換えましょう。

変更を保存するために「ファイル」から「保存」を選びます。これだけでコードは完了です。

試しに実行してみましょう。まず「再生ボタン」「虫ボタン」の右にある部分で実行する関数を選びます。このコードで実行するのは「remindEvents」関数です。選んだら「再生ボタン」を押します。

remindEvents」関数を選んだら左にある「再生ボタン」を押します。「虫ボタン」はデバッグ用です。

最初に実行する際にGoogleから「カレンダーを利用する」権限への確認が出ます。これを許可すると、コードが走り出し…Typetalkの方に先ほど追加した予定が出力されます。

プログラムのエラーがある場合は、Google Apps Scriptの方に赤いエラー表示が出ます。「カレンダーID」もしくは「メッセージの取得と投稿のURL」が間違っている可能性があるので、確認してみてください。

エラーは出ていないけど、Typetalk上に何も表示されない場合は、今日の予定が入ってない可能性があります。カレンダーを確認してみてください。

実行結果。「<<カレンダー名>>」に続いてカレンダーに入っている予定が通知されています。

毎朝8時にスクリプトを実行する

実行はできましたが、毎朝この作業を手動でやるのでは「ボット」とは言えないですね。Google Apps Scriptには「トリガー」という定期実行の仕組みがあるので、これを使って毎朝8時にこのスクリプトが実行されるようにしてみます。

「リソース」から「現在のプロジェクトのトリガー」を開きます。

Google Apps Script の画面から「リソース」の下にある「現在のプロジェクトのトリガー」を選びます。まだ何もトリガーを作っていないので「トリガーが設定されていません。今すぐ追加するにはここをクリックしてください。」というリンクが表示されていると思います。クリックして登録画面を表示しましょう。

トリガー登録画面で「remindEvents」を毎日「午前8時〜9時」に自動実行されるように設定して「保存」します。

「実行」部分は実行する関数です。手動で実行した時と同じように「remindEvents」を選びます。続く部分は自動実行する間隔の設定になります。毎朝8時過ぎに一回実行するには「時間主導型」「日タイマー」「午前 8時〜9時」を選んで「保存」ボタンを押します。

さて、後は明日の朝のお楽しみ。予定が入ってないと何も出力されず寂しいので、カレンダーに明日の予定を追加して、今日のところは寝てしまいましょう。


翌朝8時過ぎに、無事ボットから予定が通知されたでしょうか?

以上で「Google カレンダーに入っている今日の予定を毎朝 Typetalk 上でお知らせする」ボットの完成です。今回のコードは単純ですが、Google Apps Script に慣れればこれを雛形にいろいろなボットが作れます。

上では触れていませんが Typetalk のボットアカウントにはトピックへの投稿やボットへのメンションがあった際に、外部 URL を呼び出す「Webhook」という仕組みもあり、弊社で実際に動いているボットはこれを利用しています。「”today” や “tomorrow” もしくは特定の日付を話しかけられると、その日の予定を表示する」機能もついています。

今回作成したシンプルなボットと「Webhook」を利用したボット、両方のコードはヌーラボの Github上で公開されていますので自由に利用してください。

それでは皆さま、Typetalk でボットと楽しい毎日を!