Blue で作ったアプリから Google スプレッドシートに保存・メール送信する手順とサンプルコード
Blue で作るアプリは、Google Apps Script(GAS)の WebApp 機能を使って Google スプレッドシートや Gmail と連携できます。Blue は中継せず、アプリのフロントエンドから GAS の URL に直接送信します。新しいアカウント開設や追加課金は不要で、お持ちの Google アカウントだけで始められます。
主なユースケース: 問い合わせフォーム → スプシ保存/申し込みフォーム → スプシ保存 + 確認メール/スプシのデータをアプリで一覧表示/アンケート集計。
ブラウザで WebApp URL を直接開き、エラーが出ずにレスポンス(doGet を定義していれば JSON)が返れば OK です。
function doPost(e) {
try {
const data = JSON.parse(e.postData.contents);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheet.appendRow([new Date(), data.name || "", data.email || "", data.message || ""]);
return ContentService
.createTextOutput(JSON.stringify({ ok: true }))
.setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService
.createTextOutput(JSON.stringify({ ok: false, error: String(err) }))
.setMimeType(ContentService.MimeType.JSON);
}
}
function doGet(e) {
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const rows = sheet.getDataRange().getValues();
const headers = rows[0];
const items = rows.slice(1).map(row => {
const obj = {};
headers.forEach((h, i) => { obj[h] = row[i]; });
return obj;
});
return ContentService
.createTextOutput(JSON.stringify({ ok: true, items: items }))
.setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService
.createTextOutput(JSON.stringify({ ok: false, error: String(err) }))
.setMimeType(ContentService.MimeType.JSON);
}
}
function doPost(e) {
try {
const data = JSON.parse(e.postData.contents);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheet.appendRow([new Date(), data.name || "", data.email || "", data.message || ""]);
if (data.email) {
const ownerEmail = Session.getActiveUser().getEmail();
MailApp.sendEmail({ to: ownerEmail, subject: "新しいお問い合わせ", body: `名前: ${data.name}\nメール: ${data.email}\n\n${data.message}` });
MailApp.sendEmail({ to: data.email, subject: "お問い合わせを受け付けました", body: `${data.name} 様\n\nお問い合わせありがとうございます。改めてご連絡いたします。` });
}
return ContentService.createTextOutput(JSON.stringify({ ok: true })).setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({ ok: false, error: String(err) })).setMimeType(ContentService.MimeType.JSON);
}
}
メール送信のクォータ: 個人 Gmail は 1 日 100 通、Workspace は 1 日 1500 通(2026 年時点)。
コードはパターン 1〜3 と同じで構いません。違いはデプロイ時に「アクセスできるユーザー」を 「(あなたのドメイン) 内の全員」 にする点だけです。社外には見せず、社内では Google ログインの手間なく使いたい場合の中間解で、シートの ACL も尊重されます。
CORS 回避のため、POST は Content-Type: text/plain で送ります(application/json だとブラウザが preflight を投げて失敗します)。
const GAS_URL = "https://script.google.com/macros/s/AKfycbz.../exec";
document.getElementById("contact-form").addEventListener("submit", async (e) => {
e.preventDefault();
const formData = {
name: document.getElementById("name").value,
email: document.getElementById("email").value,
message: document.getElementById("message").value,
};
try {
const res = await fetch(GAS_URL, {
method: "POST",
headers: { "Content-Type": "text/plain;charset=utf-8" },
body: JSON.stringify(formData),
});
const data = await res.json();
alert(data.ok ? "送信しました" : "送信に失敗しました: " + data.error);
} catch (err) {
alert("通信エラー: " + err.message);
}
});
静的アプリ(HTML + JS)では URL をコード内に直書きします。バックエンド付きアプリ(Python / Node.js / PHP)では Blue の 設定 の「汎用 Secrets」に保存した名前を環境変数として参照します。
| データの種類 | 推奨モード |
|---|---|
| 連絡先・問い合わせ・予約 | URL-as-token(既定) |
| 社内に閉じた業務データ | URL-as-token、または Workspace ドメイン制限 |
| 社外秘の業務データ | Workspace ドメイン制限 |
| 第三者のセンシティブ個人情報(健康・財務) | OAuth + Sheets API 直接 |
| 決済情報・パスワード | GAS 連携は使わない(Stripe 等の専用 SaaS) |
| 項目 | 個人 Gmail | Workspace |
|---|---|---|
| スクリプト実行時間 / 日 | 90 分 | 6 時間 |
| メール送信数 / 日 | 100 通 | 1500 通 |
| URL Fetch 呼び出し / 日 | 20,000 回 | 100,000 回 |
| Cold start | 最初の呼び出し時に数秒 | |
これらの制約はユーザー側で管理します。スケール時にボトルネックになる場合は Cloud Run / Cloudflare Workers 等への移行を検討してください。
運営者側で個人情報保護法 / GDPR 上の通知義務が生じることが多いため、フォーム下部に以下のような通知を入れることを推奨します。
<p class="privacy-notice">
このフォームに入力された情報は Google サービスに送信され、本ページの運営者が管理します。
Google のデータ取り扱いは Google プライバシーポリシーに従います。
</p>