Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

やりたいこと

タスクと作業日の入力されたスプレッドシートから、
その日作業する必要のあるタスクを整形して
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 ができました。
うれしい。

yuzuru_xa
Frontend Engineer / Osaka twitter: https://twitter.com/yuzuru_190921
un-t
インターネットビジネスを中心とした企画、設計、デザイン、システム、運用、マーケティング、リサーチ等の総合的なクリエイティブファームです。
https://www.un-t.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away