共有スプレッドシートって、いつの間にか誰かが更新してて「え、今それ変わってたの!?」ってなりがちですよね…。気づくのが遅れると、確認や対応も後ろ倒しになって地味にストレスです。
そこで便利なのが GASのonEdit です。シートが編集された瞬間に、「誰が・どこを・どう変えたか」 をSlackにポンっと自動通知できます。しかも最短ならコピペでOKです。
この記事では、まず「通知が1回届く」ところまで一気にやって、そこから 通知がうるさくならない工夫、まとめ貼り付けで爆発しない対策、そして Webhookを安全に扱うコツや よくあるエラーの直し方まで、図解つきでやさしく説明します。ここまで読めば、チームでもちゃんと回る通知にできますよ。
まずは全体像:何が起きたら通知されるの?
登場人物(シート/GAS/スラック/Webhook)
編集→通知までの流れ(1枚図で)
「編集」→「GAS」→「Webhook」→「Slack」だけです。
できること/苦手なこと(最初に知っておく)
最短で動く!コピペで作る「1回通知」テンプレ
スラック側:Incoming Webhookを作る(最短ルート)
- Slackでアプリを作る(名前は何でもOK)
- 「Incoming Webhooks」をON→「Add New Webhook」
- 通知したいチャンネルを選んで、Webhook URLをコピー
※昔の「カスタム連携版Incoming WebHooks」は“古い方式”扱いなので、できればアプリ方式が安心です。
GAS側:スクリプト作成~保存場所(プロパティ)まで
- スプレッドシートで「拡張機能 → Apps Script」を開く
- Webhook URLはコードに直書きしないで、スクリプトプロパティに保存します(あとで安全に守りやすいです)
onEditの基本:どの情報が取れる?
通知文テンプレ:シート名/セル位置/前→後/リンク
下をそのままコピペして、setWebhook()のURLだけ自分のに差し替えてください。
function setWebhook() {
PropertiesService.getScriptProperties()
.setProperty('SLACK_WEBHOOK_URL', '<ここにWebhook URL>');
}
function onEdit(e) {
const webhook = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK_URL');
if (!webhook) return;
const range = e.range;
const sheet = range.getSheet();
const ss = sheet.getParent();
const a1 = range.getA1Notation();
const before = (e.oldValue === undefined) ? '(なし)' : String(e.oldValue);
const after = (e.value === undefined) ? '(空)' : String(e.value);
const link = ss.getUrl() + '#gid=' + sheet.getSheetId() + '&range=' + a1;
const text = `更新あり:${sheet.getName()} ${a1}\n${before} → ${after}\n${link}`;
UrlFetchApp.fetch(webhook, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({ text }),
muteHttpExceptions: true
});
}
※リンクは「#gid=...&range=A1」形式で、そのセルにだいたい一発で飛べます。
まずは「通知が1回届く」までのチェックリスト
通知がうるさい!を解決する「通知しないルール」集
onEditはちょっと触っただけでも毎回反応します。なのでコツはシンプルで、最初に「通知しない条件」を並べて、当てはまったら即returnです。これだけでSlackが平和になりますよ。
シート名で絞る(このシートだけ通知)
「連絡したいシート」だけに限定します。
例:申請と進捗だけ通知、他は無視。
列で絞る(ステータス列だけ通知)
通知したい列だけにします(例:ステータス列=E列だけ)。
現場で一番効きます。ムダ打ちが一気に減ります。
ヘッダー行・空欄→空欄を無視する
値が特定になったら通知(承認/完了/要対応)
「ステータスがこの言葉になったら通知」方式です。
例:承認 / 完了 / 要対応 のときだけ送る。
プルダウン(選択式)にしておくと、表記ゆれも減ってさらにラクです。
チャンネル分けの考え方(運用がラクになる)
「全部1チャンネル」はだいたい荒れます。最初から分けるのが正解です。
※GASがしんどい人向けに、ノーコード自動化(Zapier/Make系:無料枠〜月額数千円〜)を“選択肢”として持つのもアリです。
まとめ貼り付けで通知が爆発する問題の止め方
「範囲が大きい編集」は1通にまとめる
コピペで10行ドン!みたいな編集は、1セルずつ通知すると地獄です。なので最初から
「1セル=いつもの通知」/「複数セル=まとめ通知」 に分けちゃいましょう。
例:A2:A11 を貼り付け → 「10行まとめて更新されました(前→後は省略)」みたいに1通だけ。
const cellCount = e.range.getNumRows() * e.range.getNumColumns();
if (cellCount > 1) {
// まとめ貼り付け扱いで1通だけ送る
return;
}
多すぎる時は省略してリンクだけ送る
範囲が大きいほど、中身を全部Slackに載せるほど読みにくいです。
なので 「どのシートのどの範囲?」+リンク だけ送って、詳細はシートで見てもらうのが勝ちです。
(Slackは“読む場所”じゃなくて“気づく場所”でOKです。)
連続編集の間引き(一定時間はまとめる)
短時間に連打されると通知が流れます。クールダウンで間引くと平和です。
「最後の通知から30秒以内なら送らない」みたいな雑ルールでも、現場だとめちゃ効きます。
const cache = CacheService.getScriptCache();
const last = Number(cache.get('last_notice') || 0);
if (Date.now() - last < 30000) return; // 30秒は黙る
cache.put('last_notice', String(Date.now()), 300);
現場向けの落としどころ(厳密さより運用)
全部の変更をSlackで追うのは、だいたい無理ゲーです。おすすめはこの割り切りです。
「通知はうるさくない」「でも後から追える」で、チームが揉めにくくなりますよ。
「誰が編集した?」が出ない理由と、現実的な解決策
まず最初に言っておきますね。編集した人が取れないのは、あなたのミスじゃないです。onEditは便利なんですが、「誰が」を取るのは状況によって難しいことがあるんです。
取れる場合/取れない場合を先に整理
取れない時の表示ルール(不明でOKにする)
通知文は割り切って、
「編集者:不明」 でOKにしちゃいましょう。代わりに シート名・セル位置・前→後・リンク があれば、たいてい追えます。
代替案:入力者列・担当者列を運用で追加する
現場で一番ラクなのはこれです。
チームで揉めないための小さなルール
onEditとトリガーの違い:どっちを選べばいい?
「シンプルなonEdit」と「インストール型」の違い
ざっくり言うと、
| 比較 | シンプルonEdit | インストール型トリガー |
|---|---|---|
| 設定 | ほぼ不要 | 追加設定が必要 |
| 権限(承認) | 基本なし | 最初に承認が必要 |
| 外部送信(Slack等) | 詰まりやすい | 安定しやすい |
| チーム運用 | クセが出やすい | 向いてる |
※Slack通知みたいに外へ送る処理は、インストール型のほうがハマりにくいです。
判断基準(個人用/チーム用/必要な情報)
つまずきやすい権限(承認)をやさしく説明
インストール型は最初に「このスクリプト、Slackに送っていいですか?」みたいな許可取りが入ります。
ここでOKしないと、通知が出なかったりエラーになったりします。怖く見えますが、普通の手続きです。
設定手順の手短なチェックリスト
うまくいかない時のデバッグ手順(10分で切り分け)
「なんか届かない…」時は、上から順に見るだけでだいたい直せます。見る順番は URL → 権限 → トリガー → 絞り込み条件 → Slack側 です。
実行ログの見方(どこで止まった?)
Apps Scriptを開いて、左の 「実行」(または「実行数/Executions」)から最新の実行を開くと、エラー行が見えます。
途中経過を見たい時は、通知前に console.log() を置くと便利です。
console.log('ここまで来た:' + e.range.getA1Notation());
Webhookの返事を確認する(成功/失敗の見分け)
Slackに投げた結果は「返事(ステータスコード)」でわかります。muteHttpExceptions:trueにして、返事をログに出すと一気に切り分けできます。
const res = UrlFetchApp.fetch(webhook, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({ text }),
muteHttpExceptions: true
});
console.log('code=' + res.getResponseCode());
console.log(res.getContentText());
よくあるエラー集(権限/URL/トリガー)
二重通知・通知ゼロの典型パターン
| 症状 | ありがち原因 | 直し方 |
|---|---|---|
| 二重に届く | シンプルonEdit+インストール型が両方動いてる/トリガーが2個ある | 片方だけにする(基本はインストール型に寄せる) |
| 1通も来ない | Webhook未保存/承認してない/条件で弾いてる | まず条件を全部外して「1回通知」まで戻す |
| まとめ貼り付けで来ない | 「複数セルはreturn」で止めてる | まとめ用の1通通知に切り替える |
※運用の小ワザとして、失敗した時だけ別チャンネル(例:#gas-errors)に通知を飛ばすと、「壊れてたのに誰も気づかない」を防げます。
すぐ使える運用例(在庫・申請・問い合わせ・進捗)
ここはそのままマネできるように、全部 「見る列」→「通知条件」→「通知文(1行)」 の3点セットでいきます。
※列名は例なので、あなたのシートに合わせて置き換えてOKです。
申請:ステータスが「承認」になったら通知
在庫:数がしきい値以下になったら通知
問い合わせ:新しい行が追加されたら通知
進捗表:担当や期限が変わったら通知
コツ:通知文は長くしないで、「何が起きたか」+リンクで十分です。Slackは“気づく場所”にして、詳細はシートに飛ばすのがいちばん続きます。
安全に続けるコツと、次の伸ばし方
Webhook URLを漏らさない置き場所(直書きNG)
Webhook URLは、見られたら誰でも投稿できる鍵みたいなものです。なのでコードにベタ書きはやめて、スクリプトプロパティに入れて運用するのが基本です。
通知に載せない情報ルール(社外秘対策)
Slackは便利ですが、通知に全部出すと危ないです。おすすめのルールはこれです。
もっと自由に:Bot方式・ノーコードへの発展
「メンションしたい」「スレッドにしたい」「ボタンを押させたい」みたいに欲が出てきたら次の道があります。
- Botトークン方式:投稿の自由度が上がる(メンションや細かい制御がしやすい)
- ノーコード自動化(Zapier/Make系):GASが苦手でも組める。小規模なら無料枠〜、本格だと月額課金のイメージ
- 通知・監視系アドオン:社内で管理しやすくしたい時の選択肢
よくある質問
- QonEditが反応しません。何を見ればいいですか?
- A
まずはここを順番にチェックしてください。
- 本当に「手でセルを編集」しましたか?(貼り付けや関数変更だと挙動が変わることがあります)
- 対象のシート・列でreturnしてませんか?(絞り込み条件が強すぎる)
- インストール型トリガーを設定しましたか?(Slack送信はこれが安定です)
- Q通知が0件です。Webhook URLが悪いんですか?
- A
可能性あります。あるあるはこの3つです。
- URLに余計な空白が入ってる
- 別チャンネル用のURLを貼った
- URLをコードに直書きしてて、共有や更新で事故ってる
→ プロパティ保存にして、ログでResponseCodeを見るのが早いです。
- Q「承認が必要」みたいな画面が出て怖いです…
- A
大丈夫です、普通の手続きです。Slackに送る=外部通信なので、Googleが「許可しますか?」って聞いてきます。
インストール型トリガーを使う場合は、最初に承認しないと動きません。
- Q
e.oldValueが取れません(undefinedになります) - A
よくあります。
- 初回入力(空欄→入力)だと、
oldValueが無いことが多いです - 複数セル編集や貼り付けでも崩れがちです
→ 記事のテンプレみたいに「(なし)」表示でOKにするのが現実的です。
- 初回入力(空欄→入力)だと、
- Q「誰が編集したか」を出したいのに出ません
- A
これもよくある落とし穴で、状況によって取れないことがあります。
なのでおすすめは、通知では 編集者は「不明」でOKにして、代わりに
入力者列/担当者列を運用で追加する方法です。揉めにくいです。
- Qまとめ貼り付けで通知が爆発します。止められますか?
- A
止められます。
- 複数セル編集は「まとめ通知1通」にする
- 内容は省略して「範囲+リンク」だけにする
これでSlackが荒れなくなります。
- Q二重に通知が来ます。なぜですか?
- A
だいたい原因はこれです。
- シンプルonEditとインストール型トリガーが両方動いてる
- トリガーが2個付いてる
→ 片方に統一(おすすめはインストール型)で解決しやすいです。
- Q通知が多すぎて、チャンネルが使い物になりません…
- A
「通知する条件」より先に、通知しない条件を増やすのがコツです。
- このシートだけ
- この列だけ(例:ステータス列だけ)
- ヘッダー行は無視
- 空欄→空欄は無視
さらに重要通知とログ通知でチャンネル分けすると運用がラクです。
- QSlackに飛ぶリンクを押しても、セルにうまく飛べません
- A
まずは「シートに飛べてるか」を確認してください。セルジャンプは環境でズレることもあります。
対策としては、通知文に- シート名
- セル位置(A1)
- リンク
の3点があれば、最悪でもすぐ探せます(ここが大事です)。
- Q安全面が心配です。Webhookって漏れたらヤバいですか?
- A
はい、Webhook URLは実質「投稿できる鍵」なので、漏れたら危ないです。
- コードに直書きしない(プロパティに入れる)
- 通知には社外秘や個人情報を載せない(リンク中心に)
- もし漏れた疑いがあれば、Slack側でWebhookを作り直して差し替えが安全です。
