GASからGoogle Chatに
通知する方法
バックアップ完了・フォーム受付・エラー発生などを、Incoming Webhook(スペースに一方向で投稿できる受信用URL)を使ってGoogle Chatへ自動通知する方法を、動くコードで解説します。
Table of Contents
Google Chat通知の全体像
GASからGoogle Chatに通知する一番手軽な方法は、スペースごとに発行するIncoming Webhook(受信用のURL)へJSONをPOSTするやり方です。 APIキーやOAuth認証は不要で、Webhook URLに認証情報が含まれているため、UrlFetchApp(GASから外部へHTTPリクエストを送る機能)でそのURLにデータを送るだけで投稿できます。
全体の流れは次の3ステップです。仕組みはSlackのWebhook通知とほぼ同じで、送るJSONの構造だけが異なります。
STEP 1
Webhookを作る
通知したいスペースでWebhookを作成し、URLを発行する
STEP 2
URLを保管する
発行したURLをPropertiesServiceに安全に保存する
STEP 3
JSONを送る
UrlFetchAppでテキストやカードのJSONをPOSTする
Webhookの取得とURLの安全な保管
まず通知先のスペースでWebhookを作成します。Google Chatで対象スペースを開き、スペース名のメニューから 「アプリと統合」→「Webhook」→「Webhookを追加」を選び、名前を付けて作成すると、https://chat.googleapis.com/...{key}&{token}のようなURLが発行されます。Webhookの作成メニューは、組織の管理設定で有効になっている必要があります。
このURLを知っている人は誰でもそのスペースに投稿できます。パスワードと同じ扱いで、コードに直書きせずPropertiesServiceのスクリプトプロパティに保存しましょう。エディタの「プロジェクトの設定」→「スクリプト プロパティ」から、 キー名CHAT_WEBHOOK_URLで登録しておけば、以降のコードから安全に呼び出せます。
基本のテキスト通知を送る
最小構成は、{ text: "メッセージ" }というJSONをWebhook URLにPOSTするだけです。muteHttpExceptions: trueを付けて、失敗時にステータスコードをログで確認できるようにしておくと安心です。
function notifyGoogleChat(message) {
const url = PropertiesService
.getScriptProperties()
.getProperty("CHAT_WEBHOOK_URL");
const payload = { text: message };
const options = {
method: "post",
contentType: "application/json; charset=UTF-8",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
};
const res = UrlFetchApp.fetch(url, options);
const code = res.getResponseCode();
if (code !== 200) {
Logger.log("Chat通知に失敗: " + code + " / " + res.getContentText());
}
}
// 使い方
function testNotify() {
notifyGoogleChat("本日のバックアップが完了しました。");
}テキスト内では*太字*や_斜体_といった簡易的な装飾も使えます。まずはこの関数で1通送れることを確認してから、次のカード形式に進むとつまずきにくくなります。
カード形式(cardsV2)で見やすく通知する
項目が複数あるときは、cardsV2を使うとタイトル・見出し付きのカードで整理して表示できます。decoratedTextは「見出し+内容」を1行で見せるウィジェットで、受注内容やステータスの通知に向いています。
function notifyGoogleChatCard(title, subtitle, rows) {
const url = PropertiesService
.getScriptProperties()
.getProperty("CHAT_WEBHOOK_URL");
// rows は [{ label: "見出し", value: "内容" }, ...] の配列
const widgets = rows.map((row) => ({
decoratedText: {
topLabel: row.label,
text: row.value,
wrapText: true,
},
}));
const payload = {
cardsV2: [
{
cardId: "notify-card",
card: {
header: { title: title, subtitle: subtitle },
sections: [{ widgets: widgets }],
},
},
],
};
UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json; charset=UTF-8",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
});
}
// 使い方
function testCard() {
notifyGoogleChatCard("受注が入りました", "自動通知", [
{ label: "顧客", value: "株式会社サンプル" },
{ label: "金額", value: "120,000円" },
{ label: "納期", value: "2026/08/10" },
]);
}cardsV2では、ボタンや画像などさまざまなウィジェットを組み合わせられます。まずはheaderとdecoratedTextの組み合わせを押さえておけば、業務通知の大半はカバーできます。
@メンションとスレッドでまとめる
テキストに<users/all>と書くとスペース全員へのメンション、<users/ユーザーID>と書くと個人へのメンションになります。さらにWebhook URLにmessageReplyOptionを付け、ペイロードにthread.threadKeyを指定すると、同じキーの通知を1つのスレッドにまとめられます。
function notifyToThread(message, threadKey) {
const base = PropertiesService
.getScriptProperties()
.getProperty("CHAT_WEBHOOK_URL");
// 同じ threadKey の投稿を1つのスレッドにまとめる
const url = base + "&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD";
const payload = {
text: message,
thread: { threadKey: threadKey },
};
UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json; charset=UTF-8",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
});
}
// 使い方: 全員メンション + 案件番号でスレッドをまとめる
function testMention() {
notifyToThread("<users/all> 至急確認をお願いします。", "order-1024");
}案件番号や日付をthreadKeyにすると、同じ案件の通知がスレッドにぶら下がって流れが追いやすくなります。全員メンションは通知が多くなりがちなので、緊急度の高い連絡に絞るのがおすすめです。
フォーム・スプレッドシートと連携して自動通知する
通知を「送りたいタイミング」で自動発火させるには、トリガーと組み合わせます。 下記はGoogleフォームの回答が来るたびに、その内容をカードでGoogle Chatへ通知する例です。onFormSubmitトリガーで受け取るe.namedValuesから、設問名と回答をそのままカードの行に変換しています。
// フォーム送信をトリガーに、回答内容をGoogle Chatへ通知する
function onFormSubmitNotify(e) {
// e.namedValues は { "設問名": ["回答"], ... } の形
const values = e.namedValues;
const rows = Object.keys(values).map((label) => ({
label: label,
value: values[label].join(", "),
}));
notifyGoogleChatCard("フォームに新しい回答", "自動通知", rows);
}
// スプレッドシートの「フォーム送信時」トリガーをコードで登録
function createFormTrigger() {
const ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger("onFormSubmitNotify")
.forSpreadsheet(ss)
.onFormSubmit()
.create();
}同じ考え方で、onEditでセル編集を通知したり、時間主導トリガーで日次の集計結果を通知したりできます。 問い合わせの受付や在庫のしきい値超過など、「気づきたいイベント」をチャットに集約すると見落としが減ります。
エラー時だけ通知する実践パターン
自動処理では「成功時は静かに、失敗時だけ気づけるように」する運用が効果的です。try...catchで処理を囲み、例外が出たときだけ全員メンション付きで通知すれば、深夜のトリガー実行が失敗しても翌朝すぐ気づけます。
function dailyJob() {
try {
runBackup(); // 何らかの処理
notifyGoogleChat("日次バックアップが正常に完了しました。");
} catch (err) {
// 失敗したときだけ全員にメンションして気づけるようにする
notifyToThread(
"<users/all> 日次バックアップが失敗しました: " + err.message,
"daily-backup"
);
throw err; // 実行ログにも残す
}
}通知の送りすぎに注意する
すべての処理を通知するとチャットが埋もれ、肝心の通知が見落とされます。「人が対応すべきイベント」に絞るのがコツです。
送信回数の上限に配慮する
Webhookには短時間の連続投稿に対する制限があります。ループ内で1行ずつ通知するのではなく、まとめて1通のカードにする設計にすると安定します。
外部への送信内容に気をつける
通知はスペースの参加者全員が見られます。個人情報や機微な情報をそのまま流さないよう、通知する項目は必要最小限に絞りましょう。
まとめ
GASからGoogle Chatへの通知は、Incoming WebhookへUrlFetchAppでJSONをPOSTするだけで実現できます。テキストで手早く、cardsV2で見やすく、メンションとスレッドで整理し、 トリガーと組み合わせれば「気づきたいイベント」を自動でチャットに集約できます。 Webhook URLはPropertiesServiceに保管し、通知は必要なものに絞る——この2点を押さえれば、実務でそのまま使える通知の仕組みが作れます。
よくある質問
スペースごとに発行するIncoming Webhookを使う場合は、APIキーもOAuth認証も不要です。Webhook URLに認証用のkeyとtokenが含まれているため、そのURLへJSONをPOSTするだけで投稿できます。特定のスペースに一方向で通知を送るだけなら、この方法が最も手軽です。
送信の仕組み(UrlFetchAppでJSONをPOSTする)は同じですが、送るJSONの構造が異なります。Google Chatはテキストなら「text」キー、リッチ表示なら「cardsV2」キーを使います。SlackのBlock Kitとは項目名が違うため、Slack向けのペイロードはそのままでは使えません。
できます。textの中に「<users/all>」と書くとスペース全員に、「<users/ユーザーID>」と書くと個人にメンションできます。ユーザーIDはメールアドレスではなく数値のIDで、Google Chat APIやメンション時の表示から確認します。全員通知は多用すると煩わしくなるため、緊急度の高い通知に絞るのがおすすめです。
できます。Webhook URLに「&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD」を付け、ペイロードに「thread: { threadKey: '任意の文字列' }」を指定します。同じthreadKeyの投稿が同じスレッドにぶら下がるため、案件番号や日付をキーにすると通知が整理されます。
避けるべきです。Webhook URLを知っている人は誰でもそのスペースに投稿できてしまうため、パスワードと同じ扱いが必要です。PropertiesServiceのスクリプトプロパティに保存し、コードからは呼び出すだけにします。GitHubなどにコードを公開する場合は特に、URLを直書きしないよう注意してください。
GAS開発・業務Webシステムを
相談する。
Google Chat通知以外にも、フォーム連携・帳票出力・Gmail自動化など、日々の業務を自動化するGAS開発をご相談いただけます。