GASとSlack連携の全体像
Google Apps Script(GAS)はGoogleのサーバー上で動くJavaScript実行環境で、スプレッドシート・Gmail・Googleドライブなどと連携できます。このGASからSlack Incoming Webhookを使うことで、サーバーレスで定期実行するSlack通知システムを構築できます。
全体の流れは次の通りです。
GAS(定期実行) → スクレイピング or スプレッドシート参照
→ 条件判定
→ Slack Webhook POST
→ Slackチャンネルに通知
Slack Incoming Webhookの設定
- Slack API にアクセス
- 「Create New App」→「From scratch」でアプリを作成
- 「Incoming Webhooks」を有効化
- 「Add New Webhook to Workspace」でチャンネルを選択
- Webhook URLをコピー(
https://hooks.slack.com/services/xxx/yyy/zzz)
GASの基本実装
const SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/xxx/yyy/zzz';
/**
* Slackにメッセージを送信する関数
*/
function sendSlack(message) {
const payload = {
text: message,
username: '価格監視Bot',
icon_emoji: ':bell:',
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
};
UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
}
// テスト送信
function test() {
sendSlack('テスト通知です :white_check_mark:');
}
スプレッドシートから価格アラートを送る
/**
* スプレッドシートの価格データを確認してアラートを送る
*/
function checkPriceAlerts() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('価格監視');
const data = sheet.getDataRange().getValues();
// ヘッダー行をスキップ
for (let i = 1; i < data.length; i++) {
const productName = data[i][0]; // A列:商品名
const targetPrice = data[i][1]; // B列:目標価格
const currentPrice = data[i][2]; // C列:現在価格(別GASで更新)
const url = data[i][3]; // D列:商品URL
if (currentPrice <= targetPrice && currentPrice > 0) {
const message = [
`:tada: *価格アラート*`,
`商品: ${productName}`,
`目標価格: ¥${targetPrice.toLocaleString()}`,
`現在価格: *¥${currentPrice.toLocaleString()}*`,
`URL: ${url}`,
].join('\n');
sendSlack(message);
// アラート済みをD列に記録
sheet.getRange(i + 1, 5).setValue(new Date().toLocaleString('ja-JP'));
}
}
}
Slackリッチメッセージ(Block Kit)
シンプルなテキストだけでなく、Block Kitを使うとリッチなカード型メッセージを送れます。
function sendRichAlert(product) {
const payload = {
blocks: [
{
type: 'header',
text: { type: 'plain_text', text: ':bell: 価格アラート' }
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*商品名*\n${product.name}` },
{ type: 'mrkdwn', text: `*現在価格*\n¥${product.price.toLocaleString()}` },
{ type: 'mrkdwn', text: `*目標価格*\n¥${product.target.toLocaleString()}` },
{ type: 'mrkdwn', text: `*差額*\n¥${(product.target - product.price).toLocaleString()}` },
]
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: '商品を見る' },
url: product.url,
style: 'primary',
}
]
}
]
};
UrlFetchApp.fetch(SLACK_WEBHOOK_URL, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
});
}
定期実行トリガーの設定
GASには時間ベースのトリガーがあり、サーバーなしで定期実行できます。
/**
* トリガーをプログラムから設定する
*/
function setupTriggers() {
// 既存トリガーを削除
ScriptApp.getProjectTriggers().forEach(t => ScriptApp.deleteTrigger(t));
// 毎時0分に実行
ScriptApp.newTrigger('checkPriceAlerts')
.timeBased()
.everyHours(1)
.create();
// 毎朝9時にデイリーサマリー送信
ScriptApp.newTrigger('sendDailySummary')
.timeBased()
.atHour(9)
.everyDays(1)
.create();
}
エラー通知も忘れずに
スクレイピング処理でエラーが起きた場合もSlackに通知することで、問題を早期発見できます。
function runWithErrorNotification(fn) {
try {
fn();
} catch (error) {
sendSlack([
`:warning: *GASエラー発生*`,
`関数: ${fn.name}`,
`エラー: ${error.message}`,
`時刻: ${new Date().toLocaleString('ja-JP')}`,
].join('\n'));
}
}
// 使い方
function main() {
runWithErrorNotification(checkPriceAlerts);
}
弊社での活用事例
弊社では以下のSlack通知システムをGASで運用しています。
- EC価格監視:Amazon・楽天・Qoo10の価格変動をリアルタイム通知
- 在庫アラート:特定商品の在庫が回復したら即通知
- エラー監視:スクレイピングスクリプトのエラーを自動通知
- 日次サマリー:前日の収集データの集計結果を毎朝9時に通知
まとめ
GAS + Slack Webhookの組み合わせは、サーバーレスで無料・低コストに運用できる通知システムの定番です。スプレッドシートをデータストアとして使えるため、Googleの各サービスとシームレスに連携できます。
データ収集・自動通知システムの開発についてはお気軽にご相談ください。