スプレッドシートと Slack を連携させてタスク管理 bot を作る
やりたいこと
タスクと作業日の入力されたスプレッドシートから、 その日作業する必要のあるタスクを整形して Slack に毎朝 POST してくれるような タスク管理 bot を作成したい。
こんな感じの。
というわけで、bot 作成までの流れをひととおりまとめておきます。
2020/ 4/ 5 GAS の V8 ランタイム導入によりテンプレートリテラルが使用可能になったため、サンプルコードを一部変更いたしました。
準備
- Google スプレッドシート(タスクリスト)
- POST したい Slack チャンネル
- Slack Incoming Webhooks URL(後述します)
スプレッドシートはこんな感じのサンプルを用意します。
キャプチャには写っていませんが、シート名は schedule
にしておきます。
実装する必要のある機能
- スプレッドシートからデータを取得
- Slack 用にテキスト整形
- Slack に POST
- 以上のスクリプトを毎朝実行
前準備として、スクリプトから Slack に POST する機能を実装するにあたって、 Slack Incoming Webhooks という外部連携の設定を行う必要があります。
Slack Incoming Webhooks
POST したい Slack チャンネルの URL を取得、設定をします。
こちらの記事を参考にしつつ。 Slack の Webhook URL 取得手順 設定ができたら、ターミナルから簡単なメッセージを投げてみて動作確認をしてみましょう。
curl -X POST -H 'Content-type: application/json' --data '{"text":"SampleText"}' https://hooks.slack.com/services/取得したURL
上記のコマンドを実行して、Slack に SampleText が POST されれば OK です。
GAS から簡単なメッセージを投げてみる
機能実装のためのスクリプトは GoogleAppScript(GAS) に記述します。
JavaScript ベースなので、フロントエンドの方は作業しやすいのではないかと思います。
(ES6 には対応しておらず、let 宣言やテンプレートリテラルなどは使用できないようです。つらい。)
V8 ランタイム導入により ES6 記法に対応されたようですね、うれしい!
GAS では、
- 先にスクリプトを作成してスプレッドシートに紐つける方法と、
- スプレッドシートに紐ついたスクリプトを生成する 方法があるようです。
今回は後者の方法で進めていきますので、スプレッドシートのメニューから
ツール > スクリプトエディタ
で作成します。
メッセージ形成の機能を後で追加しやすいように、WebhookURL を管理する部分とメッセージの作成部分を別関数で作成します。
function sendMessage() {
//Webhook URLを以下に入力
const postUrl = "https://hooks.slack.com/services/取得したWebhookをここに入力します";
const sendMessage = createMessage();
const jsonData = {
"text": sendMessage
};
const payload = JSON.stringify(jsonData);
const options = {
"method": "post",
"contentType": "application/json",
"payload": payload
};
UrlFetchApp.fetch(postUrl, options);
}
function createMessage() {
//ここでメッセージの中身を作成します
var message = "SampleText";
return message;
}
スクリプトが準備できたら、メニューから sendMessage を実行します。 先ほどと同様、Slack に SampleText が POST されれば、GAS と Slack 連携の機能実装は完了です。
スプレッドシートのセルを取得して Slack に POST してみる
sendMessage は変更する必要がないので、createMessage の中身のみ書き換えていきます。
function createMessage() {
//spreadsheetからscheduleのシートを取得
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName("schedule");//シート名
const output = sheet.getRange(2, 3).getValue(); //C2(2行目, 3列目セル)の値を取得
return output;
}
スプレッドシートから出力するタスクを整形
スプレッドシートから必要な情報をいい感じに POST できるように、タスクを整形します。 以下のような感じで機能を実装します。
- 作業予定日に本日の日付が入力されていれば、作業内容と納品日を整形してメッセージに追加
- 備考もあれば追加
- これをデータのあるすべての行に対して実行
- タスクがなければ
本日のタスクはありません
と POST
function createMessage() {
//spreadsheetからscheduleのシートを取得
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName("schedule");
const dataObject = new Date();
const today = Utilities.formatDate(dataObject, "Asia/Tokyo", "yyyy/MM/dd");
const detailColumn = 2; //作業内容の入力されているカラム
const workDateColumn = 3; //作業日が入力されているカラム (C列)
const publishDateColumn = 4; //公開日の入力されているカラム
const commentColumn = 5; //備考が入力されているカラム
const startRow = 2; //列データはタイトルを除き2行目から
const columnFVals = sheet.getRange('C:C').getValues(); //C列の値を配列で取得
const lastRow = columnFVals.filter(String).length; //空白を除き、配列の数を取得
var taskList = ""; //タスクリスト
var output = ""; //createMessageからの最終的な出力
for (row = startRow; row <= lastRow; row++) {
var detail = sheet.getRange(row, detailColumn).getValue() + " ";
//作業予定日を取得
var workDate = sheet.getRange(row, workDateColumn).getValue();
var publishDate = sheet.getRange(row, publishDateColumn).getValue();
var comment = sheet.getRange(row, commentColumn).getValue();
//日付の整形
workDate = Utilities.formatDate(workDate, "Asia/Tokyo", "yyyy/MM/dd");
publishDate = Utilities.formatDate(publishDate, "Asia/Tokyo", "MM/dd");
//今日の日付と作業予定日を比較、taskListの生成
if (today == workDate) {
taskList = `${taskList}◆ ${detail}納品日時:${publishDate} ${publishTime}` + "\n";
if (comment !== "") {
taskList = `${taskList} - ${comment}` + "\n";
}
}
}
//最終的な出力の生成
if (taskList == "") {
output = `${today}のタスクはありません`;
} else {
output = `${today}のタスクです \`\`\`${taskList}\`\`\``;
}
return output;
}
こうしてできあがったものが、一番最初に貼り付けてあったこちらになります。
タスクリストを出力するためには sendMessage 関数を実行する必要があるので、 最後に GAS が毎朝 sendMessage 関数を実行するように設定します。
関数の定期的な実行
GAS に実行タイマーを設定すれば OK です。 下記赤枠部分から実行トリガーを設定できます。
トリガーを追加
→ 以下のように設定で完了です。
これで毎日 9-10 時くらいにその日のタスクを通知してくれる bot ができました。 うれしい。