PR
広告

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

広告
Googleフォームが送信されたらslackに通知する Google
広告

タスク管理を自動通知する方法を解説します。

使用するツールは以下の通り。

  • Googleフォーム
  • Googleスプレッドシート
  • Google AI(Gemini)※ChatGPT or Claude or 他のAIツールでもOK
  • Googleプログラミング言語(Google Apps Script. 略称GAS) ※JavaScriptをベースとしたプログラミング言語
  • Slack ※Chatworkなど他のグループチャットツールでもOK

フォームが送信されたらその内容を通知する

広告

Googleフォームを作成

Googleフォームを選択

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

空白のフォームを選択

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

以下のようにフォームを作成したとする。作成が終わったら「公開」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

「リンクを知っている全員」になっていることを確認して「公開」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

GoogleフォームをGoogleスプレッドシートに連結する

上で作成したフォームの「回答」タブを選択して「スプレッドシートにリンク」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

「新しいスプレッドシートを作成」を選択して「作成」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用
広告

Googleスプレッドシート

以下のようにGoogleフォームで作成したフォームの内容を反映した、Googleスプレッドシートが作成される。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

右上の鎖マークのアイコンをクリックしてURLをコピーする。 
ブラウザに張り付けて開く。

フォームに記入したら「送信」をクリックすると以下のようにGoogleスプレッドシートにGoogleフォームに作成した内容が記録される。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

チャットツールであるSlackにチャンネル「タスク」を作成する。この「タスク」にGoogleフォームが送信されたらその内容を通知するのが、今回作業のゴール。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用
広告

Google AI(Gemini)

今回、Google AIのGeminiを使っているが、ChatGPT or Claude or 他のAIツールを使用してもOK。

Geminiで以下のようにプロンプトを入力する。

Googleスプレッドシートの内容をSlackに自動転送するGoogle Apps Scriptを作成して。
タブ名:フォームの回答 1
A列:タイムスタンプ
B列:担当者
C列:タスク
D列:期限

以下のコードが出力された。

/**
 * GoogleスプレッドシートからSlackに新しい行を自動転送するスクリプト
 */

// 設定値
const SLACK_WEBHOOK_URL = 'YOUR_SLACK_WEBHOOK_URL_HERE'; // SlackのWebhook URLを設定
const SHEET_NAME = 'フォームの回答 1';
const LAST_ROW_PROPERTY = 'LAST_PROCESSED_ROW';

/**
 * メイン処理:新しい行をSlackに送信
 */
function sendNewRowsToSlack() {
  try {
    // スプレッドシートを取得
    const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    const sheet = spreadsheet.getSheetByName(SHEET_NAME);
    
    if (!sheet) {
      console.error(`シート "${SHEET_NAME}" が見つかりません`);
      return;
    }
    
    // 最後に処理した行を取得(初回は1行目のヘッダーをスキップするため1を設定)
    const properties = PropertiesService.getScriptProperties();
    let lastProcessedRow = parseInt(properties.getProperty(LAST_ROW_PROPERTY)) || 1;
    
    // 現在のデータ行数を取得
    const currentLastRow = sheet.getLastRow();
    
    // 新しい行がない場合は終了
    if (currentLastRow <= lastProcessedRow) {
      console.log('新しい行はありません');
      return;
    }
    
    // 新しい行のデータを取得
    const newRowsRange = sheet.getRange(lastProcessedRow + 1, 1, currentLastRow - lastProcessedRow, 4);
    const newRowsData = newRowsRange.getValues();
    
    // 各新しい行をSlackに送信
    newRowsData.forEach((row, index) => {
      const rowNumber = lastProcessedRow + 1 + index;
      sendRowToSlack(row, rowNumber);
    });
    
    // 最後に処理した行番号を更新
    properties.setProperty(LAST_ROW_PROPERTY, currentLastRow.toString());
    
    console.log(`${newRowsData.length}行の新しいデータをSlackに送信しました`);
    
  } catch (error) {
    console.error('エラーが発生しました:', error);
    sendErrorToSlack(error.message);
  }
}

/**
 * 単一の行データをSlackに送信
 */
function sendRowToSlack(rowData, rowNumber) {
  const [timestamp, assignee, task, deadline] = rowData;
  
  // データが空の場合はスキップ
  if (!timestamp && !assignee && !task && !deadline) {
    return;
  }
  
  // タイムスタンプをフォーマット
  const formattedTimestamp = timestamp ? Utilities.formatDate(new Date(timestamp), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss') : '未設定';
  const formattedDeadline = deadline ? Utilities.formatDate(new Date(deadline), 'Asia/Tokyo', 'yyyy/MM/dd') : '未設定';
  
  // Slackメッセージを構築
  const message = {
    text: "📝 新しいタスクが登録されました",
    attachments: [
      {
        color: "good",
        fields: [
          {
            title: "担当者",
            value: assignee || "未設定",
            short: true
          },
          {
            title: "タスク",
            value: task || "未設定",
            short: true
          },
          {
            title: "期限",
            value: formattedDeadline,
            short: true
          },
          {
            title: "登録日時",
            value: formattedTimestamp,
            short: true
          }
        ],
        footer: `行番号: ${rowNumber}`,
        ts: Math.floor(Date.now() / 1000)
      }
    ]
  };
  
  // Slackに送信
  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify(message)
  };
  
  try {
    const response = UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
    if (response.getResponseCode() !== 200) {
      throw new Error(`Slack送信エラー: ${response.getResponseCode()}`);
    }
    console.log(`行${rowNumber}のデータをSlackに送信しました`);
  } catch (error) {
    console.error(`行${rowNumber}のSlack送信でエラー:`, error);
    throw error;
  }
}

/**
 * エラーメッセージをSlackに送信
 */
function sendErrorToSlack(errorMessage) {
  const message = {
    text: "⚠️ スプレッドシート→Slack転送でエラーが発生しました",
    attachments: [
      {
        color: "danger",
        fields: [
          {
            title: "エラー内容",
            value: errorMessage,
            short: false
          }
        ],
        ts: Math.floor(Date.now() / 1000)
      }
    ]
  };
  
  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify(message)
  };
  
  try {
    UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
  } catch (error) {
    console.error('エラーメッセージのSlack送信に失敗:', error);
  }
}

/**
 * トリガーを設定する関数(初回実行用)
 */
function setupTrigger() {
  // 既存のトリガーを削除
  const triggers = ScriptApp.getProjectTriggers();
  triggers.forEach(trigger => {
    if (trigger.getHandlerFunction() === 'sendNewRowsToSlack') {
      ScriptApp.deleteTrigger(trigger);
    }
  });
  
  // 新しいトリガーを作成(5分間隔で実行)
  ScriptApp.newTrigger('sendNewRowsToSlack')
    .timeBased()
    .everyMinutes(5)
    .create();
    
  console.log('5分間隔のトリガーを設定しました');
}

/**
 * フォーム送信時に即座に実行するトリガー用の関数
 */
function onFormSubmit(e) {
  // フォーム送信時に即座にSlackに通知
  try {
    const sheet = e.source.getActiveSheet();
    if (sheet.getName() === SHEET_NAME) {
      const row = e.range.getRow();
      const rowData = sheet.getRange(row, 1, 1, 4).getValues()[0];
      sendRowToSlack(rowData, row);
      
      // 最後に処理した行番号を更新
      const properties = PropertiesService.getScriptProperties();
      properties.setProperty(LAST_ROW_PROPERTY, row.toString());
    }
  } catch (error) {
    console.error('フォーム送信時のエラー:', error);
    sendErrorToSlack(error.message);
  }
}

/**
 * フォーム送信トリガーを設定する関数
 */
function setupFormSubmitTrigger() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  
  // 既存のフォーム送信トリガーを削除
  const triggers = ScriptApp.getProjectTriggers();
  triggers.forEach(trigger => {
    if (trigger.getEventType() === ScriptApp.EventType.ON_FORM_SUBMIT) {
      ScriptApp.deleteTrigger(trigger);
    }
  });
  
  // フォーム送信トリガーを作成
  ScriptApp.newTrigger('onFormSubmit')
    .onFormSubmit()
    .create();
    
  console.log('フォーム送信トリガーを設定しました');
}

/**
 * 手動テスト用関数
 */
function testSlackIntegration() {
  // テストデータ
  const testData = [
    new Date(), // タイムスタンプ
    "田中太郎", // 担当者
    "テストタスクの実行", // タスク
    new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) // 期限(1週間後)
  ];
  
  sendRowToSlack(testData, 999);
  console.log('テストメッセージを送信しました');
}
広告

Google Apps Scriptにコピペ

Googleスプレッドシートのメニューバーで「拡張ツール」→「Apps Script」をクリックする。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

GAS(Goole Apps Script)の内容を張り付ける。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用
広告

Slack Incoming Webhook

Slack Incoming Webhookにアクセスする。
「Slackに追加」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

Slackに通知するチャンネル「タスク」を選択。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

「Incoming Webhook インテグレーションの追加」をクリック。表示されたURLをコピー。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

GoogleスプレッドシートをSlackに連結する

「SLACK_WEBHOOK_URL」の行に上でコピーしたURLをペースト。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

保存(①)して実行(②)する。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用
Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

「権限を確認」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

「詳細」を選択

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

「Untitled project(安全ではないページ)に移動」をクリック。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

Slackのタスクチャンネル「タスク」にフォームからの2件が表示されていることが確認できる。

Googleフォームが送信されたらslackに通知する|Gemini・Googleフォーム・slack利用

タスク依頼以外に一斉メールや様々な設定ができます。

Google
広告
広告
広告