【自動化】GASを用いてGoogleフォームの回答をSlackへ通知する仕組みを実装
はじめに
「フォームの回答が来たら、すぐにSlackで気付きたい」
業務でGoogleフォームを使っていると、こんな場面によく遭遇します。問い合わせフォーム、申込みフォーム、社内アンケート……気付くのが遅れて対応漏れにつながることもありますよね。
この記事では、Google Apps Script(GAS)を使って、Googleフォームの回答をSlackに自動通知する仕組みをハンズオン形式で作っていきます。
こんな方におすすめ
- GASを勉強中で、実用的なサンプルで手を動かしたい方
- 業務効率化や自動化に興味がある方
- Webhookを使ったAPI連携を体験してみたい方
この記事で学べること
- SlackのIncoming Webhookの設定方法
- GASから外部APIへのHTTPリクエストの送り方
- フォーム送信をトリガーにしたGASの実行方法
- Block Kitでリッチな通知メッセージを作る方法
完成イメージ
最終的に、以下の流れの自動化が完成します。
[Googleフォーム送信] → [スプレッドシートに記録] → [GASが起動] → [Slackに通知]
Slackには、回答内容と一緒にスプレッドシートへのリンクも届きます。担当者はSlackの通知をタップするだけで、すぐに回答を確認できます。
フォームからの回答画面

チャネルへの通知画面

事前準備
以下を用意してください。
- Googleアカウント
- 通知先のSlackワークスペース
- 通知用のSlackチャンネル(例:
#form-notifications)
実装手順
Step 1: SlackのIncoming Webhook URLを取得する
まずはSlack側の設定です。Incoming Webhookは、外部サービスからSlackへメッセージを送るための仕組みです。
- Slack APIにアクセスし、「Create New App」をクリック
- 「From scratch」を選び、アプリ名(例:
Form Notifier)とワークスペースを設定 - 左メニューから「Incoming Webhooks」を選び、トグルを「On」に切り替え
- 「Add New Webhook to Workspace」をクリックし、通知先のチャンネルを選択
- 発行された
https://hooks.slack.com/services/...形式のURLをコピー
Step 2: Googleフォームとスプレッドシートを準備する
- Googleドライブで新しいフォームを作成
- 質問項目を追加(例:
お名前、メールアドレス、お問い合わせ内容) - 「回答」タブから「スプレッドシートにリンク」をクリックし、新規スプレッドシートを作成
これでフォーム回答がスプレッドシートに自動で蓄積される状態になります。
Step 3: Webhook URLをスクリプトプロパティに登録する
Webhook URLをコードに直書きすると、コードを共有したときに第三者へ漏れるリスクがあります。GASには「スクリプトプロパティ」という安全な設定値置き場があるので、コードを書く前にここへ登録しておきましょう。
- リンクしたスプレッドシートを開き、メニューから
拡張機能→Apps Scriptを選択 - エディタ左メニュー下部の「プロジェクトの設定」(歯車アイコン)をクリック
- 「スクリプト プロパティ」セクションまでスクロールし、「スクリプト プロパティを追加」をクリック
- 以下を入力して「スクリプト プロパティを保存」をクリック
- プロパティ:
SLACK_WEBHOOK_URL - 値:Step 1でコピーしたWebhook URL
- プロパティ:
Step 4: GASでSlack通知のコードを書く
エディタに戻り、デフォルトのfunction myFunction()を削除して以下のコードを貼り付けてください。
// スクリプトプロパティからWebhook URLを取得
const SLACK_WEBHOOK_URL =
PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK_URL');
/**
* フォーム送信時に実行される関数
* @param {Object} e フォーム送信イベントオブジェクト
*/
function notifyOnFormSubmit(e) {
// フォームの回答を取得
const itemResponses = e.namedValues;
// 通知メッセージを組み立てる
let message = '📨 新しいフォーム回答が届きました\n\n';
for (const question in itemResponses) {
const answer = itemResponses[question][0];
message += `*${question}*\n${answer}\n\n`;
}
// スプレッドシートのURLを末尾に追加
const sheetUrl = SpreadsheetApp.getActiveSpreadsheet().getUrl();
message += `<${sheetUrl}|スプレッドシートで確認する>`;
// Slackに送信
sendToSlack(message);
}
/**
* Slackにメッセージを送信する
* @param {string} text 送信するテキスト
*/
function sendToSlack(text) {
const payload = { text: text };
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
};
UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
}
コードのポイント解説
-
e.namedValues:フォームの質問名と回答が{質問: [回答]}の形式で格納されたオブジェクトです -
UrlFetchApp.fetch():GASから外部URLにHTTPリクエストを送るメソッドです - Slackの記法では、
*テキスト*で太字、<URL|表示テキスト>でリンク表示になります
Step 5: フォーム送信トリガーを設定する
GASをフォーム送信時に自動実行するように、トリガーを設定します。
- GASエディタの左メニューから「トリガー」(時計アイコン)を選択
- 右下の「トリガーを追加」をクリック
- 以下のように設定する
- 実行する関数を選択:
notifyOnFormSubmit - イベントのソース:
スプレッドシートから - イベントの種類:
フォーム送信時
- 実行する関数を選択:
- 「保存」をクリック(初回は権限の承認画面が表示されます)
Step 6: 動作確認
実際にフォームから回答を送信してみます。Slackに通知が届けば成功です。
通知が届かない場合は、以下を確認しましょう。
- Webhook URLが正しくコピーされているか
- 関数名がトリガー設定と一致しているか
- GASエディタの「実行数」または「実行ログ」でエラーが出ていないか
応用編:Block Kitでリッチな通知にする
シンプルなテキスト通知でも十分ですが、SlackのBlock Kitを使うとレイアウトの整った見やすい通知が作れます。
sendToSlack関数を以下のように書き換えてみましょう。
function sendToSlack(itemResponses, sheetUrl) {
// 質問と回答をフィールド配列に詰める
const fields = [];
for (const question in itemResponses) {
fields.push({
type: 'mrkdwn',
text: `*${question}*\n${itemResponses[question][0]}`,
});
}
const payload = {
blocks: [
{
type: 'header',
text: { type: 'plain_text', text: '📨 新しいフォーム回答', emoji: true },
},
{
type: 'section',
fields: fields,
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: 'スプレッドシートを開く' },
url: sheetUrl,
style: 'primary',
},
],
},
],
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
};
UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
}
合わせて、呼び出し側のnotifyOnFormSubmitも以下のように書き換えます。
function notifyOnFormSubmit(e) {
const sheetUrl = SpreadsheetApp.getActiveSpreadsheet().getUrl();
sendToSlack(e.namedValues, sheetUrl);
}
これで、ヘッダー・本文・ボタンが整理されたリッチな通知が届くようになります。
Block Kitのレイアウトを試したい方へ
Slack公式のBlock Kit Builderを使うと、ブラウザ上でビジュアル的にレイアウトを作れます。生成されたJSONをblocksにコピーするだけで利用できるので、デザインの試行錯誤がはかどります。
つまずきやすいポイント
実装中に詰まりがちな箇所をまとめます。
トリガーの選択肢を間違える
トリガー設定には似た選択肢が複数あります。今回正しいのは 「スプレッドシートから」+「フォーム送信時」 の組み合わせです。「フォームから」を選ぶとフォーム編集時の発火になり、回答送信ではトリガーされません。
e.namedValuesがundefinedになる
GASエディタから手動でnotifyOnFormSubmitを実行すると、引数eが渡されないためundefinedになります。動作確認はかならず実際のフォームから送信して行ってください。
デバッグ時にWebhook URLをログ出力しない
Logger.log(SLACK_WEBHOOK_URL)のように実行ログにURLを出力すると、プロジェクトの閲覧権限を持つ人にURLが見えてしまいます。デバッグ用のログ出力は、確認後すぐに削除する習慣をつけましょう。
万一URLが漏れたときはすぐに再発行する
スクリプトプロパティで管理していても、共有ミスなどでURLが外部に漏れる可能性はゼロではありません。漏洩の疑いがある場合は、Slack App管理画面から該当のIncoming Webhookを削除し、新しいURLを発行します。新URLでスクリプトプロパティを更新すれば、旧URL経由の不正投稿は遮断されます。
まとめ
GASとSlackのIncoming Webhookを組み合わせると、フォーム回答の見落としを防ぐ通知システムが30分ほどで作れます。
ポイントを振り返ります。
- SlackのIncoming Webhookが連携の入り口
- スクリプトプロパティでWebhook URLを安全に管理する
-
UrlFetchApp.fetch()で外部APIにリクエストを送れる - 「フォーム送信時」トリガーで自動実行を実現できる
- Block Kitを使えば見やすい通知メッセージが作れる
この仕組みは応用が効きます。たとえば次のような展開が可能です。
- 特定のキーワードを含む回答だけ通知する
- 営業時間外の問い合わせは別チャンネルに振り分ける
- Chatworkに通知先を変える(エンドポイントとリクエスト形式を差し替える)
業務に合わせてカスタマイズしてみてください。次回はChatwork版や、複数の通知先を条件で出し分けるパターンを書く予定です。
最後まで読んでいただき、ありがとうございました。
Discussion