LoginSignup
30
28

More than 3 years have passed since last update.

スプレッドシートとSlackを連携させてタスク管理botを作る

Last updated at Posted at 2019-09-22

やりたいこと

タスクと作業日の入力されたスプレッドシートから、
その日作業する必要のあるタスクを整形して
Slack に毎朝 POST してくれるような
タスク管理 bot を作成したい。

こんな感じの。
スクリーンショット 2019-09-22 14.47.04.png
というわけで、bot 作成までの流れを一通りまとめておきます。

2020/ 4/ 5
GAS の V8 ランタイム導入によりテンプレートリテラルが使用可能になったため、サンプルコードを一部変更いたしました。

準備

  • Google スプレッドシート(タスクリスト)
  • POST したい Slack チャンネル
  • Slack Incoming Webhooks URL(後述します)

スプレッドシートはこんな感じのサンプルを用意します。
キャプチャには写っていませんが、シート名は schedule にしておきます。
スクリーンショット 2019-09-22 14.46.10.png

実装する必要のある機能

  • スプレッドシートからデータを取得
  • 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 では、
1. 先にスクリプトを作成してスプレッドシートに紐つける方法と、
2. スプレッドシートに紐ついたスクリプトを生成する
方法があるようです。

今回は後者の方法で進めていきますので、スプレッドシートのメニューから
ツール > スクリプトエディタ
で作成します。

メッセージ形成の機能を後で追加しやすいように、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;
}

こうして出来上がったものが、一番最初に貼り付けてあったこちらになります。
スクリーンショット 2019-09-22 14.47.04.png
タスクリストを出力するためには sendMessage 関数を実行する必要があるので、
最後に GAS が毎朝 sendMessage 関数を実行するように設定します。

関数の定期的な実行

GAS に実行タイマーを設定すれば OK です。
下記赤枠部分から実行トリガーを設定することができます。
スクリーンショット 2019-09-22 15.11.17.png

トリガーを追加 → 以下のように設定で完了です。
スクリーンショット 2019-09-22 15.16.46.png

これで毎日 9-10 時くらいにその日のタスクを通知してくれる bot ができました。
うれしい。

30
28
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
28