Table of Contents
開発環境
- Node.js: 10.15.0
- @slack/bolt: 1.2.0
Bolt
Slackが公式で出しているSlackアプリを作成するためのNode.jsフレームワークです。
どのようなものなのかサクッと試したい方は公式で入門ガイド がありますので、そこから試すことができます。
TimeTree API
TimeTreeでは最近APIが公開され、プログラムからTimeTreeへのアクセスが可能となりました。
でたばかりなのでまだまだできることは少ない(2019年9月8日現在)ですが、予定作成はできるようなので使ってみようと思います。
作成したSlackアプリ
予定作成デモ: /timetree create [カレンダー名] [予定タイトル] [開始日] [終了日]
/timetree
コマンドで自分のカレンダー一覧と予定作成ができるSlackコマンドを作ってみました。
- カレンダー一覧:
/timetree list
- 予定作成:
/timetree create [カレンダー名] [予定名] [開始日] [終了日]
完成したもののソースコードは公開しています。
ソースコード解説 (Bolt - Slackコマンドのリスニングと応答)
メインのコードだけ載せます。
index.js
const { getCalendarListMessage, createEvent } = require("./timetree");
// timetreeコマンドのリスニング
app.command("/timetree", async ({ command, ack, say }) => {
// コマンドリクエストを確認
ack();
const [ commandName, calendarName, title, startAt, endAt ] = command.text.split(/(\s+)/);
switch (commandName) {
case "list": // カレンダー一覧コマンド
const calendarList = await getCalendarListMessage();
say(calendarList);
break;
case "create": // 予定作成コマンド
const result = await createEvent(calendarName, title, startAt, endAt);
say(result);
break;
default: // 該当なし
say("そのコマンドには対応していません");
}
});
commannd()
メソッドでコマンドのリスニングを行なって、イベントを受け取ったことを ack()
で確認します。
その後、 say()
メソッドで応答して結果を返しています。
ソースコード解説 (TimeTree API - カレンダー一覧取得)
timetree.js
const fetch = require("node-fetch");
const TIMETREE_PERSONAL_TOKEN = process.env.TIMETREE_PERSONAL_TOKEN;
// TimeTree APIへのリクエスト
const fetchApi = (url, method = "GET", body = null) => {
return fetch(url, {
method,
body,
headers: {
"Content-Type": "application/json",
Accept: "application/vnd.timetree.v1+json",
Authorization: `Bearer ${TIMETREE_PERSONAL_TOKEN}`
}
})
.then(res => res.json())
.catch(errorHandler);
};
// エラーハンドラー
const errorHandler = err => {
console.error(err);
};
// カレンダー一覧GET
const getCalendars = () => {
return fetchApi("https://timetreeapis.com/calendars").then(res => res.data);
};
// カレンダー一覧メッセージ取得
module.exports.getCalendarListMessage = () => {
return getCalendars()
.then(calendars => {
if (calendars.length <= 0) return "カレンダーが見つかりませんでした";
return calendars.reduce(
(reducer, calendar) => reducer + `- ${calendar.attributes.name}\n`,
"以下のカレンダーが見つかりました \n"
);
})
.catch(errorHandler);
};
これはTimeTree APIを使ってカレンダー一覧データを取得する箇所です。
TimeTreeへの認証はパーソナルアクセストークンで行なっています。
https://timetreeapis.com/calendars に対してGETしてきて応答メッセージを作成しています。
ソースコード解説 (TimeTree API - 予定作成)
timetree.js
// イベントPOST
const postEvent = (calendarId, params) => {
return fetchApi(
`https://timetreeapis.com/calendars/${calendarId}/events`,
"POST",
params
).then(res => {
console.log(res);
return res;
});
};
// カレンダーを名前で取得
const getCalendarByName = name => {
return getCalendars().then(calendars =>
calendars.find(calendar => calendar.attributes.name === name)
);
};
// 日付バリデーション
const validateDate = date =>
/([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/.test(date);
// 予定を作成
module.exports.createEvent = (calendarName, title, startAt, endAt) => {
return getCalendarByName(calendarName).then(calendar => {
// 入力値バリデーション
if (!calendar) return "指定したカレンダーが見つかりませんでした...";
if (!title) return "予定タイトルを指定してください";
if (!validateDate(startAt))
return "正しいフォーマットで開始日をしてしてください";
if (!validateDate(endAt))
return "正しいフォーマットで終了日をしてしてください";
// POSTパラメータ
const params = {
data: {
attributes: {
title: title,
category: "schedule", // 予定
all_day: true, // 終日
start_at: `${startAt}T00:00:00.000Z`,
end_at: `${endAt}T00:00:00.000Z`
},
relationships: {
label: {
data: {
id: `${calendar.id},1`, // ラベル1
type: "label"
}
}
}
}
};
return postEvent(calendar.id, JSON.stringify(params)).then(
() => "予定を作成しました"
);
});
};
カレンダー一覧取得 → 入力されたカレンダー名にマッチするカレンダーIDを取得 → カレンダーIDを元に予定を作成
という流れになります。
今回は終日のみサポートしていますが、 all_day
をfalseにすれば細かい時間での予定を作成することも可能です。
https://timetreeapis.com/calendars/:calendarId/events に対してPOSTすることでTimeTreeに予定を作成することができます。
指定できるパラメータは POST /calendars/:calendar_id/events で確認することができます。
Google App Engine(GAE)へのデプロイ
完成したBoltアプリをデプロイします。
ngrokを使ってローカルで動作確認する 方法もあるので、本番環境にデプロイする前にこちらで行うのもありです。
GCPアカウントを作成、gcloud CLIをインストール すれば簡単にできます。
app.yaml
runtime: nodejs10
includes:
- secret.yaml
GAEへデプロイする設定として runtime
を指定します。
secret.yaml
env_variables:
SLACK_SIGNING_SECRET: "自分のSlack Sigining Secret"
SLACK_BOT_TOKEN: "自分のSlack Bot User Oauth Access Token"
TIMETREE_PERSONAL_TOKEN: "自分のTimeTree Personal Token"
さらに必要な環境変数を設定します。
SlackやTimeTreeの環境変数に関しては次に説明します。
設定が終えたら以下コマンドでデプロイできます。
$ gcloud app deploy
Slackアプリの設定
Boltアプリをデプロイできたら、次にSlackアプリの設定を行います。
やることとしては以下になります。
- Slack Appの作成
- Basic InformationからSigning Secretの取得
- Bot Userの追加
- Install AppからBot User Oauth Access Tokenの取得
- Slashコマンドの追加(この時にGAEにデプロイしたリクエストURLを設定)
詳しくは
でわかりやすく解説されています。
TimeTree Personal Access Tokenの取得
https://timetreeapp.com/personal_access_tokens からTimeTree APIへアクセスするためのPersonal Access Tokenを作成します。
取得したSlackとTimeTreeの各トークン情報などは環境変数として設定してください。
まとめ
Boltを利用することで簡単にSlackアプリを作成することができました。
今後TimeTree APIも予定一覧の取得などもできるようになれば、Slack上で予定の通知、確認などができると思うので期待しています!