0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GAS】スプレッドシート管理できるSlackのリマインダーをつくってみた

Posted at

現在 Google Apps Script(GAS)を使ったツールを開発しており、今回の作業で初めてGASに触れました。実際に扱ってみると、できることの幅が広く、とても興味深いものでした。

そもそもGASとは

Google Apps Script(GAS) は、Googleが提供しているクラウド上で動作するスクリプト言語です。
JavaScriptをベースにしており、普段使っているGoogleの各サービス(スプレッドシート、Gmail、カレンダー、フォームなど)を自動化・連携させることができます。

たとえば、次のような処理を簡単に作成することができます。

  • Googleスプレッドシートに入力されたデータを自動で整形する
  • 指定時刻にGmailを自動送信する
  • Googleフォームの回答をもとにSlack通知を送る
  • カレンダーの予定を毎朝メールで配信する

また、SlackやChatwork、Notion、LINEなどの外部サービスと連携することも可能です。
Webhookを使えば、GASから外部サービスへ通知を送ったり、逆に外部サービスからGASを呼び出したりといった、柔軟な仕組みを作ることができます。

GASにはさまざまな活用方法がありますが、今回はその一例として、簡易的なリマインダーを作成する手順を紹介します。

手順

1.GASの設定

  1. Google スプレッドシートを新規作成
  2. 「拡張機能」→「Apps Script」を選択
    スクリーンショット 2025-11-06 19.26.38.png
  3. 「ファイル」からファイルを2つ作成し下記コードをコピペ
    code.gs
    // メイン処理:1分ごとに自動実行
    function checkAndSendReminders() {
      try {
        const sheet =
          SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
        if (!sheet) {
          Logger.log('エラー: シート "' + SHEET_NAME + '" が見つかりません');
          return;
        }
    
        const lastRow = sheet.getLastRow();
        if (lastRow < 2) {
          Logger.log("送信するリマインダーがありません");
          return;
        }
    
        const dataRange = sheet.getRange(2, 1, lastRow - 1, 4);
        const data = dataRange.getValues();
        const now = new Date();
        let sentCount = 0;
    
        for (let i = 0; i < data.length; i++) {
          const row = data[i];
          const reminderDate = row[0];
          const reminderTime = row[1];
          const message = row[2];
          const sent = row[3];
    
          if (!reminderDate || !message || sent === "送信済み") {
            continue;
          }
    
          const reminderDateTime = combineDateTime(reminderDate, reminderTime);
    
          if (reminderDateTime <= now) {
            const success = sendToSlack(message);
    
            if (success) {
              sheet.getRange(i + 2, 4).setValue("送信済み");
              sentCount++;
              Logger.log(`リマインダー送信成功: ${message.substring(0, 30)}...`);
            }
          }
        }
    
        Logger.log(`処理完了: ${sentCount}件のリマインダーを送信しました`);
      } catch (error) {
        Logger.log("エラーが発生しました: " + error.toString());
      }
    }
    
    function combineDateTime(date, time) {
      const resultDate = new Date(date);
    
      if (time instanceof Date) {
        resultDate.setHours(time.getHours());
        resultDate.setMinutes(time.getMinutes());
      } else if (typeof time === "string" && time.includes(":")) {
        const timeParts = time.split(":");
        resultDate.setHours(parseInt(timeParts[0], 10));
        resultDate.setMinutes(parseInt(timeParts[1], 10));
      }
    
      return resultDate;
    }
    
    function sendToSlack(message) {
      try {
        const payload = {
          text: message,
        };
    
        const options = {
          method: "post",
          contentType: "application/json",
          payload: JSON.stringify(payload),
          muteHttpExceptions: true,
        };
    
        const response = UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
        const responseCode = response.getResponseCode();
    
        if (responseCode === 200) {
          return true;
        } else {
          Logger.log(
            "Slack送信エラー: " + responseCode + " - " + response.getContentText()
          );
          return false;
        }
      } catch (error) {
        Logger.log("Slack送信で例外が発生: " + error.toString());
        return false;
      }
    }
    
    // 初期セットアップ:スプレッドシート設定、Slack接続テスト、トリガー設定を一括実行
    function initialize() {
      Logger.log("🚀 初期セットアップを開始します...");
    
      // 1. スプレッドシート初期設定
      const ss = SpreadsheetApp.getActiveSpreadsheet();
      let sheet = ss.getSheetByName(SHEET_NAME);
    
      if (!sheet) {
        sheet = ss.insertSheet(SHEET_NAME);
      }
    
      const headers = ["日付", "時刻", "メッセージ", "送信済み"];
    
      sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
    
      const headerRange = sheet.getRange(1, 1, 1, headers.length);
      headerRange.setBackground("#4285f4");
      headerRange.setFontColor("#ffffff");
      headerRange.setFontWeight("bold");
    
      sheet.setColumnWidth(1, 120);
      sheet.setColumnWidth(2, 80);
      sheet.setColumnWidth(3, 400);
      sheet.setColumnWidth(4, 100);
    
      const now = new Date();
      const oneMinuteAgo = new Date(now.getTime() - 1 * 60000);
      const hours = String(oneMinuteAgo.getHours()).padStart(2, "0");
      const minutes = String(oneMinuteAgo.getMinutes()).padStart(2, "0");
    
      const sampleData = [
        [
          now,
          `${hours}:${minutes}`,
          "📋 これはテストリマインダーです(即座に送信されます)",
          "",
        ],
      ];
    
      sheet
        .getRange(2, 1, sampleData.length, sampleData[0].length)
        .setValues(sampleData);
    
      Logger.log("✅ スプレッドシートの初期設定が完了しました");
    
      // 2. トリガー設定
      const triggers = ScriptApp.getProjectTriggers();
      triggers.forEach((trigger) => {
        if (trigger.getHandlerFunction() === "checkAndSendReminders") {
          ScriptApp.deleteTrigger(trigger);
        }
      });
    
      ScriptApp.newTrigger("checkAndSendReminders")
        .timeBased()
        .everyMinutes(1)
        .create();
    
      Logger.log("✅ トリガーを設定しました(1分ごとに実行)");
      Logger.log(
        "📝 サンプルリマインダーは次のトリガー実行時に送信されます(1分以内)"
      );
      Logger.log("🎉 初期セットアップが完了しました!");
    }
    
    // トリガー削除
    function deleteTrigger() {
      const triggers = ScriptApp.getProjectTriggers();
      triggers.forEach((trigger) => {
        if (trigger.getHandlerFunction() === "checkAndSendReminders") {
          ScriptApp.deleteTrigger(trigger);
        }
      });
    
      Logger.log("✅ トリガーを削除しました");
    }
    
    
    Config.gs
    // Slack設定
    const SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
    
    // スプレッドシート設定
    const SHEET_NAME = "リマインダー";
    

2.Slack APIの設定

  1. Slack APIにアクセス → 「Create New App」
  2. 「From scratch」→ アプリ名入力 → ワークスペース選択
    スクリーンショット 2025-11-04 21.04.48.png
  3. 左サイドバー「OAuth & Permissions」内の「Bot Token Scopes」→「chat:write.public」を追加

「chat:write」の追加の承認が出るのでそれも追加してください

4. 左サイドバー「Incoming Webhooks」→ ON にする
5. 「Add New Webhook to Workspace」→ チャンネル選択 → 「許可する」
6. Webhook URL をコピー
7. コピーしたWebhook URLをConfig.gsのSLACK_WEBHOOK_URLに設定

3.初期設定の実行

  1. GAS エディタで関数 initialize を選択 → 実行(▶️)
    スクリーンショット 2025-11-17 10.44.13.png

  2. 初回実行時は権限の承認が必要

    1. 認証が必要です→「OK」をクリック
    2. アカウントを選択してください→自分のアカウントを選択
    3. このアプリは Google で確認されていません→「詳細」をクリック
    4. 「プロジェクト名(安全ではないページ)に移動」をクリック
    5. プロジェクト名 が Google アカウントへのアクセスを求めています→「続行」をクリック
      スクリーンショット 2025-11-06 19.56.12.png

スプレッドシートに戻ってみるとリマインダーが設定されているのがわかりますね✅
あとは表内にタスクを入力していけば自動でリマインドしてくれます!
スクリーンショット 2025-11-26 21.34.11.png

まとめ

今回紹介したリマインダーのように、GASを使えば身近な業務を簡単に自動化できます。
ぜひ、スプレッドシートや他のツールと組み合わせて、自分の業務にも取り入れてみてください。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?