スポンサーリンク

スプレッドシート更新をスラック通知!GAS onEdit入門

スポンサーリンク
この記事は約16分で読めます。
スポンサーリンク

共有スプレッドシートって、いつの間にか誰かが更新してて「え、今それ変わってたの!?」ってなりがちですよね…。気づくのが遅れると、確認や対応も後ろ倒しになって地味にストレスです。

そこで便利なのが GASのonEdit です。シートが編集された瞬間に、「誰が・どこを・どう変えたか」 をSlackにポンっと自動通知できます。しかも最短ならコピペでOKです。

この記事では、まず「通知が1回届く」ところまで一気にやって、そこから 通知がうるさくならない工夫まとめ貼り付けで爆発しない対策、そして Webhookを安全に扱うコツよくあるエラーの直し方まで、図解つきでやさしく説明します。ここまで読めば、チームでもちゃんと回る通知にできますよ。

  1. まずは全体像:何が起きたら通知されるの?
    1. 登場人物(シート/GAS/スラック/Webhook)
    2. 編集→通知までの流れ(1枚図で)
    3. できること/苦手なこと(最初に知っておく)
  2. 最短で動く!コピペで作る「1回通知」テンプレ
    1. スラック側:Incoming Webhookを作る(最短ルート)
    2. GAS側:スクリプト作成~保存場所(プロパティ)まで
    3. onEditの基本:どの情報が取れる?
    4. 通知文テンプレ:シート名/セル位置/前→後/リンク
    5. まずは「通知が1回届く」までのチェックリスト
  3. 通知がうるさい!を解決する「通知しないルール」集
    1. シート名で絞る(このシートだけ通知)
    2. 列で絞る(ステータス列だけ通知)
    3. ヘッダー行・空欄→空欄を無視する
    4. 値が特定になったら通知(承認/完了/要対応)
    5. チャンネル分けの考え方(運用がラクになる)
  4. まとめ貼り付けで通知が爆発する問題の止め方
    1. 「範囲が大きい編集」は1通にまとめる
    2. 多すぎる時は省略してリンクだけ送る
    3. 連続編集の間引き(一定時間はまとめる)
    4. 現場向けの落としどころ(厳密さより運用)
  5. 「誰が編集した?」が出ない理由と、現実的な解決策
    1. 取れる場合/取れない場合を先に整理
    2. 取れない時の表示ルール(不明でOKにする)
    3. 代替案:入力者列・担当者列を運用で追加する
    4. チームで揉めないための小さなルール
  6. onEditとトリガーの違い:どっちを選べばいい?
    1. 「シンプルなonEdit」と「インストール型」の違い
    2. 判断基準(個人用/チーム用/必要な情報)
    3. つまずきやすい権限(承認)をやさしく説明
    4. 設定手順の手短なチェックリスト
  7. うまくいかない時のデバッグ手順(10分で切り分け)
    1. 実行ログの見方(どこで止まった?)
    2. Webhookの返事を確認する(成功/失敗の見分け)
    3. よくあるエラー集(権限/URL/トリガー)
    4. 二重通知・通知ゼロの典型パターン
  8. すぐ使える運用例(在庫・申請・問い合わせ・進捗)
    1. 申請:ステータスが「承認」になったら通知
    2. 在庫:数がしきい値以下になったら通知
    3. 問い合わせ:新しい行が追加されたら通知
    4. 進捗表:担当や期限が変わったら通知
  9. 安全に続けるコツと、次の伸ばし方
    1. Webhook URLを漏らさない置き場所(直書きNG)
    2. 通知に載せない情報ルール(社外秘対策)
    3. もっと自由に:Bot方式・ノーコードへの発展
  10. よくある質問
スポンサーリンク

まずは全体像:何が起きたら通知されるの?

登場人物(シート/GAS/スラック/Webhook)

  • スプレッドシート:編集する場所
  • GAS:編集を見張って通知文を作る係
  • Slack:通知を受け取る場所
  • Webhook:Slackの「受け取り口」

編集→通知までの流れ(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の基本:どの情報が取れる?

  • e.range:どのセル(範囲)か
  • e.value:変更後
  • e.oldValue:変更前(取れない時もあります。まずは気にしなくてOK)

通知文テンプレ:シート名/セル位置/前→後/リンク

下をそのままコピペして、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回届く」までのチェックリスト

  • setWebhook()を1回実行して、プロパティにURLが入った
  • シートを手で編集(貼り付けじゃなく1セル)してみた
  • Slackに1通届いた(届いたら次で“うるささ対策”に進めます)

通知がうるさい!を解決する「通知しないルール」集

onEditはちょっと触っただけでも毎回反応します。なのでコツはシンプルで、最初に「通知しない条件」を並べて、当てはまったら即returnです。これだけでSlackが平和になりますよ。

シート名で絞る(このシートだけ通知)

「連絡したいシート」だけに限定します。
例:申請進捗だけ通知、他は無視。

列で絞る(ステータス列だけ通知)

通知したい列だけにします(例:ステータス列=E列だけ)。
現場で一番効きます。ムダ打ちが一気に減ります。

ヘッダー行・空欄→空欄を無視する

  • 1行目(見出し)は通知しない
  • 空欄→空欄みたいな「実質変わってないやつ」も無視
  • ついでに、空欄に戻しただけも通知しない運用にすると静かです(必要なら逆に通知でもOKです)

値が特定になったら通知(承認/完了/要対応)

「ステータスがこの言葉になったら通知」方式です。
例:承認 / 完了 / 要対応 のときだけ送る。
プルダウン(選択式)にしておくと、表記ゆれも減ってさらにラクです。

チャンネル分けの考え方(運用がラクになる)

  • 大事:承認・要対応 → #重要
  • ログ:それ以外 → #ログ(見たい人だけ見る)

「全部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で追うのは、だいたい無理ゲーです。おすすめはこの割り切りです。

  • Slack:重要な変化だけ(ステータス列とか)
  • それ以外:編集ログを別シートに残す(無料でOK)

「通知はうるさくない」「でも後から追える」で、チームが揉めにくくなりますよ。

「誰が編集した?」が出ない理由と、現実的な解決策

まず最初に言っておきますね。編集した人が取れないのは、あなたのミスじゃないです。onEditは便利なんですが、「誰が」を取るのは状況によって難しいことがあるんです。

取れる場合/取れない場合を先に整理

  • 取れやすい:自分だけで使うシート/権限(承認)をちゃんと通した設定/組織アカウントで運用
  • 取れないことが多い:共有シートでいろんな人が編集/簡易版のonEditだけで運用/権限が弱い状態

取れない時の表示ルール(不明でOKにする)

通知文は割り切って、
「編集者:不明」 でOKにしちゃいましょう。代わりに シート名・セル位置・前→後・リンク があれば、たいてい追えます。

代替案:入力者列・担当者列を運用で追加する

現場で一番ラクなのはこれです。

  • 「入力者」列(プルダウンで名前を選ぶ)
  • 「担当者」列(必ず入れる)
  • 申請系なら、そもそもフォーム入力に寄せる(自動で記録が残ります)

チームで揉めないための小さなルール

  • ステータス変える人は、担当者もセットで入れる
  • 重要な変更は「備考」に一言だけ残す(長文いりません)
  • “誰が問題”は技術で殴るより、ルールでスッと解決がだいたい勝ちです

onEditとトリガーの違い:どっちを選べばいい?

「シンプルなonEdit」と「インストール型」の違い

ざっくり言うと、

  • シンプルonEdit=自動ドア(勝手に開くけど、できることは少なめ)
  • インストール型トリガー=受付(最初に許可が必要だけど、できることが増える)
比較シンプルonEditインストール型トリガー
設定ほぼ不要追加設定が必要
権限(承認)基本なし最初に承認が必要
外部送信(Slack等)詰まりやすい安定しやすい
チーム運用クセが出やすい向いてる

※Slack通知みたいに外へ送る処理は、インストール型のほうがハマりにくいです。

判断基準(個人用/チーム用/必要な情報)

  • 自分だけで軽く:まずシンプルで試す → ダメならインストール型へ
  • 共有シートでちゃんと運用:最初からインストール型がおすすめ
  • 二重通知が怖い:シンプルとインストール型を“両方”有効にしない(ここ大事です)

つまずきやすい権限(承認)をやさしく説明

インストール型は最初に「このスクリプト、Slackに送っていいですか?」みたいな許可取りが入ります。
ここでOKしないと、通知が出なかったりエラーになったりします。怖く見えますが、普通の手続きです。

設定手順の手短なチェックリスト

  • Apps Scriptを開く
  • 左の「時計マーク(トリガー)」→「トリガーを追加」
  • 実行する関数:通知用の関数(例:onEdit でもOK)
  • イベントのソース:スプレッドシートから
  • イベントの種類:編集時(On edit)
  • 保存→承認が出たらOKする
  • 二重通知が出たら:関数名を変えて「インストール型だけ」に寄せる(H2-7で詳しく潰します)

うまくいかない時のデバッグ手順(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());
  • 200 なら基本OK
  • 400 前後なら「payloadの形」や「URL違い」率高めです

よくあるエラー集(権限/URL/トリガー)

  • 権限系:シンプルonEditだと外部送信が止まりがち → インストール型にする&承認する
  • URL系:Webhookが空/余計な空白/別のURLを貼った
  • トリガー系:関数名違い、トリガー未設定、複数トリガーで混乱

二重通知・通知ゼロの典型パターン

症状ありがち原因直し方
二重に届くシンプルonEdit+インストール型が両方動いてる/トリガーが2個ある片方だけにする(基本はインストール型に寄せる)
1通も来ないWebhook未保存/承認してない/条件で弾いてるまず条件を全部外して「1回通知」まで戻す
まとめ貼り付けで来ない「複数セルはreturn」で止めてるまとめ用の1通通知に切り替える

※運用の小ワザとして、失敗した時だけ別チャンネル(例:#gas-errors)に通知を飛ばすと、「壊れてたのに誰も気づかない」を防げます。

すぐ使える運用例(在庫・申請・問い合わせ・進捗)

ここはそのままマネできるように、全部 「見る列」→「通知条件」→「通知文(1行)」 の3点セットでいきます。
※列名は例なので、あなたのシートに合わせて置き換えてOKです。

申請:ステータスが「承認」になったら通知

  • 見る列ステータス 列(例:E列)
  • 通知条件:値が 承認 になった時だけ
  • 通知文(例)
    ✅ 承認されました:申請ID=123(担当:山田)

在庫:数がしきい値以下になったら通知

  • 見る列在庫数 列(例:C列)
  • 通知条件:在庫数が 5 以下になったら通知(数字に直すのがポイント)
  • 通知文(例)
    ⚠ 在庫が少ないです:商品A 在庫=4(発注お願いします)

問い合わせ:新しい行が追加されたら通知

  • 見る列受付日時 or 問い合わせ内容 列(例:A列かB列)
  • 通知条件:その行の「キーになるセル」が空→埋まった(=新規っぽい)
  • 通知文(例)
    📩 新規問い合わせ:田中さん(内容あり)※シートへ

進捗表:担当や期限が変わったら通知

  • 見る列担当 列(例:B列)と 期限 列(例:D列)
  • 通知条件:B列またはD列が編集されたら通知(それ以外は無視)
  • 通知文(例)
    🗓 進捗更新:タスク=〇〇(担当/期限が変更されました)

コツ:通知文は長くしないで、「何が起きたか」+リンクで十分です。Slackは“気づく場所”にして、詳細はシートに飛ばすのがいちばん続きます。

安全に続けるコツと、次の伸ばし方

Webhook URLを漏らさない置き場所(直書きNG)

Webhook URLは、見られたら誰でも投稿できる鍵みたいなものです。なのでコードにベタ書きはやめて、スクリプトプロパティに入れて運用するのが基本です。

通知に載せない情報ルール(社外秘対策)

Slackは便利ですが、通知に全部出すと危ないです。おすすめのルールはこれです。

  • 個人情報(住所・電話・メール・氏名のフルなど)は載せない
  • 金額・契約・社外秘は載せない(「更新あり+リンク」だけで十分)
  • どうしても必要なら、Slack側は閲覧できる人を絞る(チャンネル設計で守る)

もっと自由に:Bot方式・ノーコードへの発展

「メンションしたい」「スレッドにしたい」「ボタンを押させたい」みたいに欲が出てきたら次の道があります。

  • Botトークン方式:投稿の自由度が上がる(メンションや細かい制御がしやすい)
  • ノーコード自動化(Zapier/Make系):GASが苦手でも組める。小規模なら無料枠〜、本格だと月額課金のイメージ
  • 通知・監視系アドオン:社内で管理しやすくしたい時の選択肢

よくある質問

Q
onEditが反応しません。何を見ればいいですか?
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

「通知する条件」より先に、通知しない条件を増やすのがコツです。

  • このシートだけ
  • この列だけ(例:ステータス列だけ)
  • ヘッダー行は無視
  • 空欄→空欄は無視
    さらに重要通知とログ通知でチャンネル分けすると運用がラクです。
Q
Slackに飛ぶリンクを押しても、セルにうまく飛べません
A

まずは「シートに飛べてるか」を確認してください。セルジャンプは環境でズレることもあります。
対策としては、通知文に

  • シート名
  • セル位置(A1)
  • リンク
    の3点があれば、最悪でもすぐ探せます(ここが大事です)。
Q
安全面が心配です。Webhookって漏れたらヤバいですか?
A

はい、Webhook URLは実質「投稿できる鍵」なので、漏れたら危ないです。

  • コードに直書きしない(プロパティに入れる)
  • 通知には社外秘や個人情報を載せない(リンク中心に)
  • もし漏れた疑いがあれば、Slack側でWebhookを作り直して差し替えが安全です。
タイトルとURLをコピーしました