GAS:Google SheetsとSlackを使ったシンプルな自動タスクリマインダーのサンプル

必要なスキル

Slackのワークフロー、Incoming Webhooks設定、Google App Scriptの基本を理解をしていること

概要

Slackへの自動投稿としては簡単な利用方法です。スプレッドシートへ登録したリマインダー情報を指定日時にSlackチャンネルの指定ユーザーへメンション投稿します。Slack側のApp設定、Incoming Webhooksを設定する説明は省きます。

スクリプトの処理説明

スプレッドシートへ入力されたリマインド日時がスクリプト実行時に超えている場合に実行しています。スクリプトの実行トリガー次第で投稿するタイミングは変わってくるので即時性や毎朝まとめて送信など任意でトリガー設定させると良い。

  1. シートの取得:
    • Reminderシートを取得し、全データを読み込みます。
  2. 現在時刻の取得:
    • 現在の日時を取得します。
  3. データのループ処理:
    • 各行のデータをループし、通知実行日時が設定されているか確認します。
  4. フラグの確認:
    • フラグが空欄またはnullであり、現在時刻が通知実行日時を過ぎている場合に処理を続行します。
  5. Slackへの通知準備:
    • SlackのWebhook URLを使用して、メッセージにユーザーIDをメンション付きで組み込み、チャンネルIDにメッセージを送信するためのペイロードを作成します。
  6. Slackへの通知送信:
    • UrlFetchApp.fetchを使用して、Slackに通知を送信します。
  7. フラグの更新:
    • 通知が送信された場合、フラグをsentに更新します。
    • 通知が失敗した場合、フラグをerrorに更新します。

Spread Sheet

スプレッドシートの内容です。このサンプルではリマインド1回実行するだけです。
FlagがNullの場合にPostします。

Reminderの登録手順
下記の項目へ入力してください。登録時はFlagは空白のままにしてください。

  1. NotificationDateTime リマインドを発生させる日時を yyyy/MM/dd HH:mm:ss の形式で入力
  2. Message 投稿するメッセージを入力してください。URLなども入力して大丈夫です。
  3. UserID メンション対象がユーザーであれば、@usernameまたは@useridを入力する@を先頭につけてください。UserGroupの場合には !subteam^groupid として入力。
  4. ChannelID 投稿するチャンネルのIDを入力。

補足:ユーザーグループへメンションしたい場合は、次のルールに沿って登録
Formatting text for app surfaces
Mentioning groups 
https://api.slack.com/reference/surfaces/formatting#mentioning-groups

Sheetname: Reminder
FlagNotificationDateTimeMessageUserIDChannelID
yyyy/MM/dd HH:mm:ss
2024/06/01 15:30:00
任意の投稿内容、URLリンクなど
Don't forget the meeting!
ユーザの場合は@を付ける。ユーザーグループの場合は!subteam^を文字先頭につける
@username or @userid or !subteam^groupid
C12345678

Sample Script

サンプルのスクリプトです。
エラー確認の為に少しログ出力も書いたままにしてあります。

function sendReminders() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Reminder");
  var data = sheet.getDataRange().getValues();
  var now = new Date();

  for (var i = 1; i < data.length; i++) { // Skip header row
    var flag = data[i][0]; // A列のフラグ
    var notificationDateTimeStr = data[i][1]; // B列の通知実行日時
    var message = data[i][2]; // C列の通知メッセージ
    var userId = data[i][3]; // D列のSlackメンション対象UserID
    var channelId = data[i][4]; // E列のSlackチャンネルID

    // 通知実行日時が空の場合スキップ
    if (!notificationDateTimeStr) {
      continue;
    }

    var notificationDateTime = new Date(notificationDateTimeStr);

    if (flag !== "sent" && now >= notificationDateTime) {
      var slackURL = "https://hooks.slack.com/services/url"; // ここにWebhook URLを入力
      var payload = {
        "channel": channelId,
        "text": message + " <" + userId + ">"
      };

      var options = {
        "method": "post",
        "contentType": "application/json",
        "payload": JSON.stringify(payload)
      };

      // デバッグ用のログ出力 ここは消しちゃってOK
      Logger.log("URL: " + slackURL);
      Logger.log("Payload: " + JSON.stringify(payload));
      Logger.log("Options: " + JSON.stringify(options));

      var response = UrlFetchApp.fetch(slackURL, options);
      Logger.log("Response: " + response.getContentText());

      // フラグを "sent" に更新して再実行を防ぐ
      sheet.getRange(i + 1, 1).setValue("sent");
    }
  }
}