14
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Organization

Slackで任意のユーザのGoogleカレンダーの予定を確認するスラッシュコマンドを作る

ハンズラボ Advent Calendar 2018 9日目の記事です。

Googleカレンダー使ってますか?
G Suiteを使っている会社に勤めている方なら使っていますよね。
チームメンバーの予定を確認する時にはPCのブラウザでGoogleカレンダーを開けば一覧で見られて良いですが、電話対応時などで今すぐ予定を確認したい時などには、ブラウザでGoogleカレンダーを開き、該当の人を検索し、予定を見る……というのがなかなか億劫で時間がかかったりします。
弊社で電話をよく取ってくださる方が、ブラウザで十数人のカレンダーを開いた画面を食い入るように見ながら電話対応をしていて、これはなかなか非効率的ではないか……?と思い、簡単に予定を確認できるツールを作ることにしました。

業務中はSlackを常時開きっぱなしにしている人が多く、また非エンジニアが簡単に使えるツールになるよう、SlackのスラッシュコマンドでGoogleカレンダーの予定を確認できるようにしました。
今回は、Googleカレンダーを簡単に呼び出せるよう、GoogleAppsScript(GAS)を用いて作成します。

完成品

Slackの任意のチャンネル(DMを含む)で /getschedule @hoge yyyymmdd と入力すると、任意のSlackユーザーのGoogleカレンダーの予定を呼び出すことができるスラッシュコマンドを作成します。
スクリーンショット 2018-10-21 23.47.54.png

ここでは、Slackユーザーが登録しているメールアドレスがGmailアドレスであり、かつそのアカウントでGoogleカレンダーに予定を登録していることを前提に作成します。

手順ざっくり

  1. GASのプロジェクト作成
  2. Slackのスラッシュコマンドの作成
  3. コーディング
  4. 動作確認

1. GASのプロジェクト作成

1-1. スラッシュコマンドに必要なURLを取得

Google Apps Scriptのホーム画面を開き、左上の「新規スクリプト」ボタンをクリックします。
GAS_home.png
無題のプロジェクトが作成されます。
とりあえずコードは書かず、初期状態のままSlackのスラッシュコマンドの設定に必要なURLを取得していきます。
上部メニューの「公開」 > 「ウェブアプリケーションとして導入…」をクリックします。
GAS_manu.png

設定内容 設定値 備考
プロジェクトバージョン 新規作成 その下の入力欄はバージョンの説明
次のユーザーとしてアプリケーションを実行 自分
アプリケーションにアクセスできるユーザー 全員(匿名ユーザーを含む)
  • Slackのスラッシュコマンドでこのアプリケーションを実行する際には匿名のユーザーとなるため、匿名のユーザーでアクセスできるようにし、カレンダーの閲覧権限を得るために自分のユーザーで実行するようにします。 ※ スクショではアクセスの設定間違えました……。

GAS_installAsWebApp.png

下の「導入」ボタンをクリックすると、ウェブアプリケーションのURLが表示されます。
このURLを使用してスラッシュコマンドを作成します。
GAS_installAsWebApp_done.png

2. Slackのスラッシュコマンドの作成

2-1. Slack Appを作成

スラッシュコマンドを作成するのに必要なSlack Appを作成します。
SlackAPIのYour Appsのページを開き、右上の「Create New App」をクリックします。
YourApps.png
App NameとSlack Workspaceを設定します。App Nameはスラッシュコマンドの名前とは紐づきません。
CreateSlackApp_written.png

Slackアプリを作成すると、「Basic Information」画面になります。
「Add feature and functionality」をクリックすると、そのアプリの機能を追加することができます。
今回はスラッシュコマンドを作成するため、「Slack Commands」をクリックします。
BasicInformation_first.png
「Slash Commands」画面で「Create New Command」ボタンをクリックし、
新しくコマンドを作成します。

2-2. スラッシュコマンドを作成

CreateSlashCommand.png

設定内容 設定値
Command コマンド名
Request URL 新規作成
Short Description スラッシュコマンドの説明
Usage Hint (オプション)引数の説明など、使い方のヒント
Escape channels, users, and links sent to your app チェックしない

以上の設定が完了したら右下の「Save」をクリックしてスラッシュコマンドの作成は完了です。

2-3. Slack AppをWorkspaceに追加

スラッシュコマンドを作成しただけでは、Slack内で使用することはできません。
スラッシュコマンドが紐づいたSlack AppをSlack内に導入します。
「Basic Information」画面にて、「Install your app to your workspace」をクリックし、出てきた「Install App to Workspace」ボタンをクリックします。

BasicInformation_second.png

BasicInformation_add.png

「Authorize」をクリック

BasicInformation_third.png

ここまでできると、Slack上で作成したスラッシュコマンドが出てくるようになります。
が、実行してもエラーが返ってくるだけです。
installedApp.png

2-4. トークンを取得する

Slack Appの「Basic Information」画面内の「Add feature and functionality」、「Permissions」の順にクリックして「OAuth & Permissions」のページを開きます。
このページの「OAuth Access Token」を保存しておきます。
これはGASからSlackを使うのに必要なので、あとで使用します。

3. コーディング

3-1. とりあえず動くものを作る

実際にスラッシュコマンドから想定のレスポンスが返ってくるように、GASにコードを書いていきましょう。
まず手始めに、スラッシュコマンドに渡した引数をオウム返しさせるようにコードを書いていきます。

function doPost(e) {
  var text = e.parameter.text; // 入力された文字列を抜き出す
  var responseText = text;
  var response = { text: responseText }; // レスポンス用の文字列を生成
  var json = JSON.stringify(response) // 文字列をJSONに変換

  var output = ContentService.createTextOutput(json); // Webアプリケーションとして出力するテキストを作成
  output.setMimeType(ContentService.MimeType.JSON); // outputのメディアタイプをJSONに設定

  return output;
}

これだけ書けば、あとは responseText に入れる値をゴリゴリ作っていくだけです。

3-2. Slackのユーザーのメールアドレスを取得する

次に、SlackのAPIを使ってユーザーのメールアドレスを取得して返す関数を書いていきます。
が、その前にライブラリにSlackAppを追加しましょう。
GASのメニュー リソース > ライブラリ を選択し、Library Keyに M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO を入力してSlackAppを追加しましょう。
また、Slackを使用するためにトークンが必要となります。コードに直書きしてもいいですが、ここはプロパティに書き込みましょう。
GASのメニュー ファイル > プロジェクトのプロパティ を選択し、「スクリプトのプロパティ」タブをクリックします。
「行を追加」をクリックし、プロパティに「token」、値に先ほど保存した「OAuth Access Token」を入力し保存します。

const prop = PropertiesService.getScriptProperties().getProperties();
Logger.log(prop.token)

上のようにプロパティに保存した値を取得できます。
これでSlackが使えるようになったので、SlackAPIを使用してユーザー一覧を取得し、その中から任意のユーザーのメールアドレスを取得していきます。

function getEmail(name) {
  const prop = PropertiesService.getScriptProperties().getProperties();
  const slackApp = SlackApp.create(prop.token);
  const list = slackApp.usersList();
  const members = list["members"];

  for(i=0; i<members.length; i++) {
    if (members[i]["name"] == name) {
      Logger.log(members[i].name);
      return members[i].profile.email
    } else {
      continue;
    }
  }
}

3-3. Googleカレンダーから予定を取得する

メールアドレスが取得できたので、Googleカレンダーから予定を取得します。
GASは標準でGoogleカレンダーを操作できます。
calendar.getEventsForDay(date) で1日分の予定のCalendarEventのArrayを取得できます。
.getStartTime().getEndTime() で予定の開始時間と終了時間を取得できますが、終日イベントは開始・終了共に 00:00 になるようです。

var calendarId = getEmail(userName);
var calendar = CalendarApp.getCalendarById(calendarId);
var date = new Date();   
var events = calendar.getEventsForDay(date);
// Slack用のテキストを整形
var responseText = name + "さんの今日の予定\n```";
if (events.length == 0) {
  responseText += "なし";
} else {
  for (var i=0; i<events.length;i++) {
    var title = events[i].getTitle();
    var startTime = HHmm(events[i].getStartTime());
    var endTime = HHmm(events[i].getEndTime());
    if (startTime == "00:00" && endTime == "00:00") {
      responseText += "\n終日: " + title;
    } else {
      responseText += "\n" + startTime + "" + endTime + ": " + title;
    }
  }
}

3-4. 完成品

予定を参照する日付などを端折って紹介してきたので、完成品のコードはこちらをご覧ください。
https://github.com/kurapy-n/GetSchedule

参考

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
14
Help us understand the problem. What are the problem?