GASでSlack・LINE通知を自動化|スプレッドシート更新を即通知する方法

スプレッドシートが更新されたら自動でSlackやLINEに通知が届く仕組み、GASなら無料で作れます!コピペOKのコード付きで完全解説します。
- GASからSlack・LINEに通知を送る仕組みと設定手順
- Slack Incoming Webhook / LINE Messaging APIの取得方法
- スプレッドシート更新時・フォーム回答時の自動通知コード
- 定期レポート(日次・週次)の自動送信とトリガー設定
- エラー対処・トラブルシューティングの実践ノウハウ
- VBAとGASの外部通知機能の比較
「実行」ボタンを押すと、スプレッドシートの更新をトリガーにSlackやLINEへ通知を送るGASの動作をシミュレーション体験できます。
3月度の売上データが更新されました。
💲 売上合計: ¥1,250,000
📈 前月比: +12.3%
👤 更新者: 田中太郎
詳細はスプレッドシートを確認してください。
GASで通知を自動化するメリットと全体像
スプレッドシートの更新確認やフォーム回答の把握を手動で行っていませんか?Google Apps Script(GAS)を使えば、SlackやLINEへの通知を完全自動化できます。サーバーもドメインも不要で、Googleアカウントさえあれば無料で構築できるのが最大の魅力です。
GASの基本がまだ不安な方は、まずGAS入門ガイドで全体像を把握しておくとスムーズに進められます。
GASで実現できる通知パターンは主に3つあります。
- イベント駆動型: スプレッドシートの編集やフォーム送信をトリガーに即時通知
- スケジュール型: 時間ベースのトリガーで定期レポートを自動送信
- 条件型: データが閾値を超えたときだけアラート通知
Slack通知 vs LINE通知 — 用途別の使い分け
SlackとLINEはどちらもGASから通知を送れますが、適した用途が異なります。以下の表で使い分けを確認しましょう。
| 比較項目 | Slack | LINE |
|---|---|---|
| 主な用途 | チーム・業務連絡 | 個人・少人数への通知 |
| メッセージ装飾 | Block Kitでリッチ表現可 | テキスト+画像+スタンプ |
| チャンネル指定 | Webhook URL単位で指定 | トークン発行先グループ |
| レート制限 | 1秒1メッセージ推奨 | 1時間1,000件(Notify) |
| 費用 | 無料プランあり | Messaging APIは無料枠あり |
チームでの業務通知にはSlack、個人のスマホに素早くプッシュ通知を送りたい場合はLINEが適しています。もちろん、両方に同時通知する構成も可能です。
GAS通知の仕組み(Webhook/API連携)
GASから外部サービスに通知を送る仕組みは非常にシンプルです。UrlFetchApp.fetch()メソッドを使って、SlackやLINEが提供するWebhook URL(またはAPIエンドポイント)にHTTP POSTリクエストを送信します。
処理の流れは以下のとおりです。
- GASスクリプトが実行される(手動・トリガー・イベント)
- 通知メッセージをJSON形式で組み立てる
UrlFetchApp.fetch()でWebhook URLにPOST送信- Slack/LINEのサーバーがメッセージを受け取り、チャンネル/トークに配信
GASのメール自動送信機能と組み合わせれば、メール+チャット通知のハイブリッド運用も実現できます。詳しくはGASメール自動送信ガイドをご覧ください。
Slack通知の設定方法
Slack Incoming Webhookの取得手順
Slackに通知を送るためには、まずIncoming Webhook URLを取得する必要があります。以下の手順で進めてください。
- Slack APIにアクセスし、「Create New App」→「From scratch」を選択
- App Nameに任意の名前(例: GAS通知Bot)を入力し、通知先のワークスペースを選択
- 左メニューの「Incoming Webhooks」をクリックし、トグルを「On」に切り替え
- 「Add New Webhook to Workspace」をクリックし、通知先チャンネルを選択して「許可する」
- 生成されたWebhook URL(
https://hooks.slack.com/services/T.../B.../xxx)をコピー
Webhook URLは秘密情報です。GitHubなどの公開リポジトリにコミットしないでください。GASではスクリプトプロパティに保存するのが安全です。
GASからSlackにメッセージを送信するコード
Webhook URLを取得したら、以下のコードでSlackにメッセージを送信できます。
/**
* Slackにシンプルなテキストメッセージを送信する
* 事前にスクリプトプロパティ「SLACK_WEBHOOK_URL」にWebhook URLを設定してください
*/
function sendSlackMessage() {
// スクリプトプロパティからWebhook URLを取得(セキュリティ対策)
const webhookUrl = PropertiesService.getScriptProperties()
.getProperty('SLACK_WEBHOOK_URL');
// 送信するメッセージを組み立てる
const payload = {
text: '【スプレッドシート通知】データが更新されました',
username: 'GAS通知Bot',
icon_emoji: ':bell:'
};
// HTTP POSTリクエストの設定
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
};
// Slackに送信
const response = UrlFetchApp.fetch(webhookUrl, options);
console.log('Slack送信結果: ' + response.getResponseCode());
}
スクリプトプロパティの設定方法: GASエディタの左メニュー「プロジェクトの設定」→「スクリプト プロパティ」で、プロパティ名をSLACK_WEBHOOK_URL、値にコピーしたWebhook URLを入力します。
リッチメッセージ(Block Kit)の送信
SlackのBlock Kitを使うと、ヘッダー・セクション・ボタンなどの構造化されたリッチメッセージを送信できます。業務通知では視認性が大幅に向上します。
/**
* SlackにBlock Kit形式のリッチメッセージを送信する
* セクション・フィールド・ボタンを含む構造化メッセージの例
*/
function sendSlackBlockKit() {
const webhookUrl = PropertiesService.getScriptProperties()
.getProperty('SLACK_WEBHOOK_URL');
// Block Kit形式のペイロード
const payload = {
blocks: [
{
type: 'header',
text: {
type: 'plain_text',
text: '📊 日次売上レポート',
emoji: true
}
},
{
type: 'section',
fields: [
{
type: 'mrkdwn',
text: '*本日の売上:*\n¥1,234,567'
},
{
type: 'mrkdwn',
text: '*前日比:*\n+12.3% 📈'
}
]
},
{
type: 'section',
fields: [
{
type: 'mrkdwn',
text: '*受注件数:*\n45件'
},
{
type: 'mrkdwn',
text: '*平均単価:*\n¥27,435'
}
]
},
{
type: 'divider'
},
{
type: 'actions',
elements: [
{
type: 'button',
text: {
type: 'plain_text',
text: 'スプレッドシートを開く'
},
url: 'https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit'
}
]
}
]
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
};
UrlFetchApp.fetch(webhookUrl, options);
console.log('Block Kitメッセージを送信しました');
}
Block KitのレイアウトはBlock Kit Builderでプレビューしながら作成できます。JSONをコピーしてGASのペイロードに貼り付けるだけなので、デザイン調整も簡単です。
Q: Slack Incoming Webhookが非推奨と聞きましたが、今から使っても大丈夫ですか?
A: Slackの「カスタムインテグレーション」は非推奨ですが、Slack App経由のIncoming Webhookは現在も公式にサポートされています。Slack Appを作成し、そこからWebhook URLを発行する方法なら問題なく利用できます。将来的な互換性の面でもこちらが推奨です。
Slack通知を導入する際、最初は全ての更新を通知していたのですが、1日50件以上の通知が飛んで「通知疲れ」が発生しました。そこで通知を「エラー発生時」「閾値超過時」「日次サマリー」の3種類に絞ったところ、チームの確認率が20%→85%に改善。通知は”本当に見てほしいもの”だけに厳選するのが成功のコツです。
LINEでExcelを気軽に学べる
LINE Notify通知の設定方法
LINE Notifyは2025年3月末でサービス終了が発表されています。ここではLINE Messaging APIを使った代替方法も併せて紹介します。既存のLINE Notify実装からの移行にも対応できる内容です。
LINE Notifyトークンの取得手順
LINE Messaging APIの設定手順(LINE Notify終了後の推奨方法):
- LINE Developersにログインし、新しいプロバイダーを作成
- 「Messaging API」チャンネルを新規作成
- チャンネルアクセストークン(長期)を発行
- 作成されたBotアカウントを友だち追加またはグループに招待
- チャンネルアクセストークンとユーザーID(またはグループID)をGASのスクリプトプロパティに保存
GASからLINE Notifyにメッセージを送信するコード
以下のコードはLINE Messaging APIを使った送信例です。LINE Notify終了後も動作する方法です。
/**
* LINE Messaging APIでテキストメッセージを送信する
* スクリプトプロパティに以下を設定:
* LINE_CHANNEL_TOKEN: チャンネルアクセストークン
* LINE_USER_ID: 送信先のユーザーID(またはグループID)
*/
function sendLineMessage() {
const token = PropertiesService.getScriptProperties()
.getProperty('LINE_CHANNEL_TOKEN');
const userId = PropertiesService.getScriptProperties()
.getProperty('LINE_USER_ID');
const url = 'https://api.line.me/v2/bot/message/push';
// 送信するメッセージ
const payload = {
to: userId,
messages: [
{
type: 'text',
text: '【スプレッドシート通知】\nデータが更新されました\n\n更新日時: ' +
Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss')
}
]
};
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': 'Bearer ' + token
},
payload: JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(url, options);
console.log('LINE送信結果: ' + response.getResponseCode());
}
画像・スタンプ付きの通知送信
LINE Messaging APIでは、テキスト以外にも画像やスタンプを送信できます。業務通知にグラフ画像を添付する場合に便利です。
/**
* LINEに画像付きメッセージとスタンプを送信する
* 画像はURLで指定(Googleドライブの共有リンクなども利用可能)
*/
function sendLineRichMessage() {
const token = PropertiesService.getScriptProperties()
.getProperty('LINE_CHANNEL_TOKEN');
const userId = PropertiesService.getScriptProperties()
.getProperty('LINE_USER_ID');
const url = 'https://api.line.me/v2/bot/message/push';
const payload = {
to: userId,
messages: [
// テキストメッセージ
{
type: 'text',
text: '📊 本日の売上レポートです'
},
// 画像メッセージ(グラフのスクリーンショットなど)
{
type: 'image',
originalContentUrl: 'https://example.com/chart-full.png',
previewImageUrl: 'https://example.com/chart-preview.png'
},
// スタンプメッセージ(任意)
{
type: 'sticker',
packageId: '11537',
stickerId: '52002734'
}
]
};
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': 'Bearer ' + token
},
payload: JSON.stringify(payload)
};
UrlFetchApp.fetch(url, options);
console.log('画像付きLINEメッセージを送信しました');
}
画像URLにはHTTPSのアクセス可能なURLを指定します。Googleドライブの場合は共有設定を「リンクを知っている全員」に変更し、https://drive.google.com/uc?id=FILE_ID形式で指定してください。
実践編|スプレッドシート更新時の自動通知
ここからは、スプレッドシートのイベントと連動した実践的な自動通知の実装を解説します。Googleフォームとの連携についてはGASフォーム連携ガイドも参考にしてください。
特定セルの変更を検知して通知
onEdit(e)トリガーを使えば、特定のセルが編集されたときだけ通知を送ることができます。以下は「ステータス」列が変更されたらSlackに通知するコードです。
/**
* 特定セルの変更を検知してSlackに通知する
* onEditトリガーで自動実行される
* 対象: 「ステータス」列(D列)が変更されたとき
*/
function onEdit(e) {
const sheet = e.source.getActiveSheet();
const range = e.range;
// 対象シートとD列(ステータス列)のみ処理
if (sheet.getName() !== '案件管理' || range.getColumn() !== 4) return;
const row = range.getRow();
const newValue = e.value;
const oldValue = e.oldValue || '(空欄)';
// 案件名(B列)を取得
const projectName = sheet.getRange(row, 2).getValue();
// Slackに通知
const webhookUrl = PropertiesService.getScriptProperties()
.getProperty('SLACK_WEBHOOK_URL');
const payload = {
text: '📝 *ステータス変更通知*\n' +
'案件名: ' + projectName + '\n' +
'変更内容: ' + oldValue + ' → ' + newValue + '\n' +
'変更者: ' + Session.getActiveUser().getEmail() + '\n' +
'更新日時: ' + Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm')
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
};
UrlFetchApp.fetch(webhookUrl, options);
}
onEdit(e)はシンプルトリガーのため、UrlFetchAppを使う場合はインストール可能トリガーとして設定する必要があります。GASエディタの「トリガー」から「編集時」にonEdit関数を登録してください。
新しい行の追加を検知して通知
フォーム回答やデータ追加で新しい行が増えたことを検知して通知するパターンです。スクリプトプロパティに前回の行数を記録して差分を検出します。
/**
* 新しい行の追加を検知してSlack・LINE両方に通知する
* 時間ベースのトリガー(1分おき等)で定期実行する
*/
function checkNewRows() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('回答一覧');
const currentLastRow = sheet.getLastRow();
// 前回チェック時の最終行を取得
const props = PropertiesService.getScriptProperties();
const previousLastRow = parseInt(props.getProperty('LAST_ROW') || '1');
// 新しい行がなければ終了
if (currentLastRow <= previousLastRow) return;
// 新しい行のデータを取得
const newData = sheet.getRange(
previousLastRow + 1, 1,
currentLastRow - previousLastRow,
sheet.getLastColumn()
).getValues();
// 通知メッセージを組み立て
let message = '🆕 新しい回答が ' + newData.length + '件 追加されました\n\n';
newData.forEach(function(row, i) {
message += '【回答' + (i + 1) + '】' + row[1] + ' / ' + row[2] + '\n';
});
// Slackに送信
sendToSlack(message);
// LINEにも送信
sendToLine(message);
// 最終行を更新
props.setProperty('LAST_ROW', String(currentLastRow));
}
/** Slack送信の共通関数 */
function sendToSlack(message) {
const webhookUrl = PropertiesService.getScriptProperties()
.getProperty('SLACK_WEBHOOK_URL');
UrlFetchApp.fetch(webhookUrl, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({ text: message })
});
}
/** LINE送信の共通関数 */
function sendToLine(message) {
const token = PropertiesService.getScriptProperties()
.getProperty('LINE_CHANNEL_TOKEN');
const userId = PropertiesService.getScriptProperties()
.getProperty('LINE_USER_ID');
UrlFetchApp.fetch('https://api.line.me/v2/bot/message/push', {
method: 'post',
contentType: 'application/json',
headers: { 'Authorization': 'Bearer ' + token },
payload: JSON.stringify({
to: userId,
messages: [{ type: 'text', text: message }]
})
});
}
条件付き通知(閾値超過アラート)
在庫数が基準値を下回ったときや、売上目標を達成したときなど、条件を満たした場合だけ通知するパターンです。不要な通知を減らして、本当に重要なアラートだけを受け取れます。
/**
* 在庫数が閾値を下回ったらアラート通知を送信する
* 時間ベースのトリガーで定期チェック
*/
function checkThresholdAlert() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('在庫管理');
const data = sheet.getDataRange().getValues();
const header = data[0]; // ヘッダー行
// 閾値を下回った商品を収集
const alerts = [];
for (let i = 1; i < data.length; i++) {
const productName = data[i][0]; // A列: 商品名
const stock = data[i][2]; // C列: 現在在庫
const threshold = data[i][3]; // D列: 発注点
if (stock <= threshold) {
alerts.push({
name: productName,
stock: stock,
threshold: threshold
});
}
}
// アラートがなければ終了
if (alerts.length === 0) return;
// 通知メッセージを組み立て
let message = '⚠️ *在庫アラート* — ' + alerts.length + '件の商品が発注点以下です\n\n';
alerts.forEach(function(item) {
message += '• ' + item.name +
': 在庫 *' + item.stock + '個*(発注点: ' + item.threshold + '個)\n';
});
sendToSlack(message);
}
Q: onEditトリガーで通知を送ると、自分の編集でも通知が来てしまいます。除外する方法は?
A: イベントオブジェクトのe.user.emailで編集者を判定し、自分のアドレスと一致する場合はreturnで早期終了させるのが定番です。また、特定のシートや列だけを監視対象にするフィルター条件を入れると、不要な通知をさらに減らせます。
在庫管理の閾値アラートを導入した倉庫では、欠品率が月平均8%→1.2%に改善しました。ポイントは、閾値をスプレッドシート上の「設定」シートで管理し、商品ごとに個別設定できるようにしたこと。季節商品は閾値を高めに設定するなど、現場の担当者がコード修正なしで調整できる仕組みにしたのが運用定着の鍵でした。
実践編|定期レポートの自動通知
日次サマリーの自動送信
毎日決まった時刻に売上サマリーをSlackに自動送信するコードです。時間ベースのトリガーで毎朝9時に実行する設定と組み合わせます。
/**
* 日次売上サマリーをSlackに送信する
* 時間主導型トリガーで毎日9:00に実行
*/
function sendDailySummary() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('売上データ');
const data = sheet.getDataRange().getValues();
// 本日の日付(時間部分をリセット)
const today = new Date();
today.setHours(0, 0, 0, 0);
// 本日分のデータを集計
let totalSales = 0;
let orderCount = 0;
for (let i = 1; i < data.length; i++) {
const rowDate = new Date(data[i][0]); // A列: 日付
rowDate.setHours(0, 0, 0, 0);
if (rowDate.getTime() === today.getTime()) {
totalSales += data[i][3]; // D列: 売上金額
orderCount++;
}
}
// 前日データ(比較用)
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
let yesterdaySales = 0;
for (let i = 1; i < data.length; i++) {
const rowDate = new Date(data[i][0]);
rowDate.setHours(0, 0, 0, 0);
if (rowDate.getTime() === yesterday.getTime()) {
yesterdaySales += data[i][3];
}
}
// 前日比の計算
const diff = yesterdaySales > 0
? ((totalSales - yesterdaySales) / yesterdaySales * 100).toFixed(1)
: '—';
const diffEmoji = diff > 0 ? '📈' : (diff < 0 ? '📉' : '➡️');
// Block Kitメッセージを送信
const webhookUrl = PropertiesService.getScriptProperties()
.getProperty('SLACK_WEBHOOK_URL');
const payload = {
blocks: [
{
type: 'header',
text: {
type: 'plain_text',
text: '📊 日次売上サマリー(' +
Utilities.formatDate(today, 'Asia/Tokyo', 'M/d') + ')',
emoji: true
}
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: '*売上合計:*\n¥' + totalSales.toLocaleString() },
{ type: 'mrkdwn', text: '*受注件数:*\n' + orderCount + '件' }
]
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: '*前日比:*\n' + diff + '% ' + diffEmoji },
{ type: 'mrkdwn', text: '*平均単価:*\n¥' +
(orderCount > 0 ? Math.round(totalSales / orderCount).toLocaleString() : '0') }
]
},
{ type: 'divider' },
{
type: 'context',
elements: [
{ type: 'mrkdwn', text: '自動送信 | ' +
Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm') }
]
}
]
};
UrlFetchApp.fetch(webhookUrl, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
});
console.log('日次サマリーを送信しました');
}
週次レポートの自動生成と通知
週次レポートでは、1週間分のデータを集計して曜日別の傾向やトップ商品を含めた詳細なサマリーを送信します。日次サマリーのコードを拡張し、getDay()で曜日別集計を追加する形で実装できます。
週次トリガーは「毎週月曜日の9時」に設定するのが一般的です。集計対象期間は前週の月曜日から日曜日までとしましょう。
トリガー設定のベストプラクティス
GASのトリガーを適切に設定することで、安定した自動通知を実現できます。
| 通知パターン | 推奨トリガー | 注意点 |
|---|---|---|
| セル変更通知 | インストール可能な「編集時」 | シンプルトリガーではUrlFetchApp不可 |
| 新規行チェック | 時間主導型(1〜5分おき) | 実行時間制限(6分/回)に注意 |
| 日次レポート | 時間主導型(特定時刻) | 指定時刻の±15分で実行される |
| 週次レポート | 時間主導型(毎週特定曜日) | 祝日チェックを追加すると便利 |
| 閾値アラート | 時間主導型(5〜15分おき) | 連続通知防止のフラグ管理が必要 |
トリガーの総数制限: 1つのプロジェクトで設定できるトリガーは最大20個です。不要なトリガーは定期的に整理しましょう。
エラー対処とトラブルシューティング
「UrlFetchApp呼び出しに失敗しました」エラー
このエラーは以下の原因で発生します。
- Webhook URLが間違っている: コピペミスや末尾の空白がないか確認
- ネットワークエラー: Slack/LINEのサーバーが一時的にダウンしている場合。
try-catchでリトライ処理を入れる - 権限不足: シンプルトリガー(
onEdit)からUrlFetchAppを呼んでいる場合。インストール可能トリガーに変更する - リクエスト上限: 無料アカウントは1日20,000回まで。超過するとエラーになる
安全なリトライ処理の実装例:
/**
* リトライ機能付きのHTTPリクエスト送信
* 一時的なエラーに対して最大3回リトライする
*/
function fetchWithRetry(url, options, maxRetries) {
maxRetries = maxRetries || 3;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = UrlFetchApp.fetch(url, options);
return response; // 成功したらレスポンスを返す
} catch (error) {
console.log('送信失敗(' + attempt + '/' + maxRetries + '回目): ' + error.message);
if (attempt === maxRetries) {
// 最大リトライ回数に達した場合はメールで通知
MailApp.sendEmail(
Session.getActiveUser().getEmail(),
'【GAS通知エラー】送信に失敗しました',
'エラー内容: ' + error.message + '\nURL: ' + url
);
throw error;
}
// 次のリトライまで待機(指数バックオフ)
Utilities.sleep(1000 * Math.pow(2, attempt));
}
}
}
Webhook URLの無効化・期限切れ対策
Slack Webhook URLが突然動かなくなる原因と対策をまとめます。
- Appが削除された: Slack管理者がAppを削除するとWebhookも無効になる。Appの管理権限を確認
- チャンネルがアーカイブされた: 通知先チャンネルがアーカイブされると送信不可。別チャンネルにWebhookを再設定
- セキュリティ対策で無効化: URLが漏洩した場合、管理者がWebhookを無効化することがある。新しいWebhookを再発行
予防策として、送信処理のレスポンスコードをチェックし、200以外が返ったらメール通知で管理者に知らせる仕組みを入れておくと安心です。
LINE Notifyのレート制限と対策
LINE Messaging APIにもレート制限があります。無料プラン(コミュニケーションプラン)では月200通までのプッシュメッセージが送信可能です。
- 通知の重複を防ぐため、送信済みフラグをスクリプトプロパティで管理する
- 複数の通知をまとめて1通にバッチ送信する
- 重要度の低い通知はSlack側に回してLINEの通数を節約する
VBAとGASの通知機能比較
Excel VBAでもSlack通知は可能ですが、GASと比べると実装の手軽さや運用性に大きな差があります。
VBAでSlack通知を送るコード例
VBAからSlackに通知を送るには、MSXML2.XMLHTTPオブジェクトを使用します。
' VBAからSlackにメッセージを送信する
' 参照設定: Microsoft XML, v6.0 が必要
Sub SendSlackFromVBA()
Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP")
Dim webhookUrl As String
webhookUrl = "https://hooks.slack.com/services/T.../B.../xxx"
Dim payload As String
payload = "{""text"":""【Excel通知】VBAからのテスト送信です""}"
http.Open "POST", webhookUrl, False
http.setRequestHeader "Content-Type", "application/json"
http.Send payload
If http.Status = 200 Then
MsgBox "Slackに送信しました", vbInformation
Else
MsgBox "送信失敗: " & http.Status & " " & http.statusText, vbCritical
End If
Set http = Nothing
End Sub
GASとVBAの外部通知比較表
| 比較項目 | GAS | Excel VBA |
|---|---|---|
| HTTP通信 | UrlFetchApp(標準搭載) | MSXML2.XMLHTTP(参照設定が必要) |
| 自動実行 | トリガーで24時間稼働 | Excelを開いている間のみ |
| スケジュール実行 | 時間主導型トリガーで簡単 | タスクスケジューラとの連携が必要 |
| JSON処理 | JSON.stringify/parseで簡単 | 文字列結合または外部ライブラリ |
| 環境依存 | ブラウザのみ(OS不問) | Windows + Excel必須 |
| セキュリティ | スクリプトプロパティで安全管理 | ソースコード内にURL直書きになりがち |
| おすすめシーン | クラウド型の自動通知全般 | 社内PCからの手動実行 |
自動通知の用途ではGASが圧倒的に有利です。VBAはExcelを閉じると実行できませんが、GASはGoogleのサーバー上で24時間365日トリガー実行されるため、通知の取りこぼしがありません。
よくある質問(FAQ)
Q. LINE Notifyは2025年3月で終了しませんか?
LINE Notifyは2025年3月末でサービス終了が発表されています。代替としてLINE Messaging APIの利用を推奨します。本記事ではLINE Messaging APIの方法も紹介しています。
Q. SlackのWebhook URLが漏洩した場合のリスクは?
第三者がそのWebhook URLを使って任意のメッセージを送信できるリスクがあります。漏洩した場合は即座にWebhookを無効化し、新しいURLを再発行してください。スクリプトプロパティに保存し、コードに直書きしないことが予防策です。
Q. GASの通知にタイムラグはありますか?
トリガー実行は通常1〜30秒で開始されます。UrlFetchAppの外部API呼び出しは数秒程度です。時間主導型トリガーは指定時刻の前後15分程度のずれが生じることがあるため、秒単位の正確性が必要な用途には向きません。
Q. 1つのGASスクリプトからSlackとLINE両方に通知できますか?
はい、1つのfunction内でSlackとLINEの両方にUrlFetchAppで送信できます。本記事の「新しい行の追加を検知して通知」セクションで、両方への同時通知コードを紹介しています。
Q. Discord通知もGASでできますか?
はい、DiscordもWebhook URLに対してUrlFetchAppでPOSTすれば通知可能です。Slackとほぼ同じ実装方法です。ペイロードのtextキーをcontentに変更するだけで動作します。
- Slack通知: Incoming Webhookを取得し、UrlFetchApp.fetch()でJSON形式でPOST送信
- LINE通知: LINE Messaging APIのチャンネルアクセストークンを使い、プッシュメッセージで送信
- 自動通知: onEditトリガーでセル変更検知、時間主導型トリガーで定期レポートを実現
- エラー対策: リトライ処理・レスポンスチェック・メール通知のフォールバックを実装
- VBAとの違い: GASはサーバーレスで24時間稼働、VBAはExcel起動中のみ。通知自動化にはGASが最適
GASによる通知自動化は、一度設定すれば手間なく運用できるのが最大のメリットです。まずはSlackの基本送信から試して、徐々に条件通知や定期レポートへと拡張していきましょう。
GAS通知設定・Slack/LINE連携・定期レポート自動化まで、
業務に合わせた最適な自動化をご提案します。
