こんにちは、凛です。夜勤明けの時間を使って、GASで小さな自動化を作り続けています。
今日は私の失敗談から始めさせてください。以前、ハンドメイドショップの問い合わせフォームを運用していたとき、「返信が遅くて不安だった」というレビューを書かれたことがあります。こちらとしては普通に翌日返信していたつもりでした。でもお客さんからすると、フォームを送信して、画面に「回答を記録しました」と出て、それっきり。届いたのか、読まれるのか、いつ返事が来るのか、何もわからないまま丸一日待たされていたわけです。
そのレビューを見た瞬間は正直へこみました。ただ、言われてみればその通りなんですよね。自分がお客の立場なら、送信直後に「受け付けました」の一通があるだけでどれだけ安心か。
なぜ「送信完了画面」だけでは足りないのか
原因をあらためて整理すると、Googleフォームの標準機能だけでは「受け取った側の音沙汰」が薄いことに尽きます。
送信完了画面は一瞬で閉じられてしまいますし、フォーム設定にある「回答のコピーを送信」も、フォームの回答をそのまま貼っただけの素っ気ない見た目です。申込番号や受付日時を含めた整ったメールにはなりません。「24時間以内に返信します」といった案内も入れられない。お客さんの不安を消すには、こちらの言葉で書いた確認メールを自動で送る仕組みが必要でした。
それを叶えるのがGASです。仕組みは一本道です。
ユーザー → Googleフォーム送信 → onFormSubmit トリガー → GAS → 自動返信メール
Googleフォームに「フォーム送信時」トリガーを設定すれば、送信のたびにGASが自動実行されます。あとは中で GmailApp.sendEmail を呼ぶだけ。
解決策:コピペで動く最短コード
私が実際に入れた対策の最小構成がこちらです。
function onFormSubmit(e) {
// フォーム回答から値を取得
const responses = e.namedValues;
const email = responses['メールアドレス'] ? responses['メールアドレス'][0] : '';
const name = responses['お名前'] ? responses['お名前'][0] : 'お客様';
const inquiry = responses['お問い合わせ内容'] ? responses['お問い合わせ内容'][0] : '';
if (!email) return; // メアドなければ送信しない
const subject = `【自動返信】お問い合わせを受け付けました|GAS Recipe`;
const body = `${name} 様
お問い合わせありがとうございます。
以下の内容で受け付けました。24時間以内に担当者よりご返信いたします。
──────────────────
${inquiry}
──────────────────
受付日時: ${new Date().toLocaleString('ja-JP')}
※このメールは自動送信です。返信不要です。
GAS Recipe 運営
https://gas-recipe.com`;
GmailApp.sendEmail(email, subject, body);
}
これだけで動きます。ポイントは、返信本文に問い合わせ内容そのものを引用していること。「あなたが送った内容はこちらです」と見せることで、お客さんの「ちゃんと届いたかな」という不安がその場で消えます。受付日時も添えれば、確認メールとしての役割は十分です。
トリガー設定(ここを間違えると動きません)
コードを貼ったら、GASエディタ左の時計アイコン → トリガーを追加で次のように設定します。
- 実行する関数:
onFormSubmit - イベントのソース: スプレッドシートから(フォーム回答が記録されるシート)
- イベントの種類: フォーム送信時
イベントのソースは「フォームから」ではなく「スプレッドシートから」のフォーム送信時を選んでください。こちらを選ぶと e.namedValues で日本語の質問名のままアクセスできて、コードが格段に読みやすくなります。
質問項目名はデバッグで確認しておく
e.namedValues のキーは、フォームの質問テキストそのものです。つまり質問文を変更したら、コード側のキーも更新しないと動かなくなります。事前に構造を見ておくと安心です。
function debugFormSubmit(e) {
console.log(JSON.stringify(e.namedValues));
}
これをonFormSubmitに含めて1回テスト送信すると、どんなキーで値が入ってくるかログで確認できます。
導入してからの変化
自動返信を入れてから、「届いていますか?」という追い問い合わせがなくなり、レビューで不安を書かれることもなくなりました。体感として一番大きかったのはCV(成約)への効きです。確認メールが即座に届くだけで、お店としての信頼感がまるで違うようで、導入後は一気にCVが上がりました。
運用を続ける中で身についたコツもあります。
まず、返信本文はスプシで管理すること。本文をコードに直書きすると、文言を変えるたびにGASを編集する必要があります。スプシのセルに本文を書いておいてGASから読み込む設計にすると、スマホのスプシアプリから文言を直せるので楽です。「季節の挨拶を変えたい」「URLを更新したい」という変更は思った以上に頻繁に起きるので、コードレスで直せる仕組みがあると運用が続きます。
もうひとつは、自分宛のテスト送信関数を別に用意すること。本番フォームを実際に送信してテストするのは地味に手間です。ダミーデータで自分宛に送るテスト関数を作っておくと、本文の見た目確認が数秒で終わります。
慣れてきたら試したいカスタマイズ
基本形が動いたら、少しずつ育てていけます。
例1: 申込番号を自動採番
function onFormSubmit(e) {
const sheet = SpreadsheetApp.getActiveSheet();
const rowNum = sheet.getLastRow();
const orderId = `GR-${new Date().getFullYear()}-${String(rowNum).padStart(5, '0')}`;
// GR-2026-00001 のようなID
// ...本文に含める
}
申込番号があるだけで、その後のやり取りが「先日のGR-2026-00001の件ですが」と一気にスムーズになります。
例2: 営業時間外は別文面
const hour = new Date().getHours();
const businessHours = hour >= 9 && hour < 18;
const replyTime = businessHours ? '本日中' : '翌営業日中';
// 本文に「${replyTime}にご返信」と入れる
夜中の問い合わせに「本日中にご返信します」と返してしまう事故を防げます。
例3: HTMLメールで装飾
const htmlBody = `
<div style="font-family: sans-serif; padding: 20px;">
<h2 style="color: #3b82f6;">お問い合わせを受け付けました</h2>
<p>${name} 様</p>
<div style="background: #f0f9ff; padding: 15px; border-left: 4px solid #3b82f6;">
${inquiry.replace(/\n/g, '<br>')}
</div>
<p style="color: #666; font-size: 12px;">受付日時: ${new Date().toLocaleString('ja-JP')}</p>
</div>
`;
GmailApp.sendEmail(email, subject, '', { htmlBody: htmlBody });
例4: 担当者にも通知
const ADMIN_EMAIL = 'admin@example.com';
const adminSubject = `[新規問い合わせ] ${name}様より`;
GmailApp.sendEmail(ADMIN_EMAIL, adminSubject, body);
回答者と運営者の両方に送って、対応漏れを防ぎます。自動返信を入れると自分の側の緊張感が緩みがちなので、この運営者通知はセットで入れるのがおすすめです。
例5: 添付PDFを自動生成
申込内容をPDF化して添付する高度なパターンもあります。修了証発行や申込控えに有効です。詳しくは フォーム回答から修了証PDFを自動発行 で解説しています。
送信上限とスパム判定には注意
無制限に送れるわけではありません。ここだけは事前に把握しておいてください。
| 制限 | 無料Gmail | Workspace |
|---|---|---|
| 1日の送信数 | 100通 | 1500通 |
| 受信側のスパム判定 | リスクあり | 比較的安全 |
申込フォームで1日100件を超える可能性があるなら、Workspace契約か、SendGrid等の外部メール配信サービスの併用を検討しましょう。
動かないときのチェックポイント
自動返信が届かない
最もよくある問題です。原因は「メールアドレス欄が空」「スパムフォルダに振り分けられた」「1日の送信上限に達した」の3つがほとんど。届かないと報告を受けたら、まずこの3点を疑ってください。送信残数は MailApp.getRemainingDailyQuota() で確認するのが手っ取り早い診断方法です。
二重送信される
トリガーが重複登録されているケースです。GASエディタのトリガー一覧を開いて、同じ関数に複数のトリガーが設定されていないかを確認し、不要なものは削除してください。ScriptApp.getProjectTriggers() でプログラムから一覧を取得して確認することもできます。
文字化けする
GmailApp.sendEmail は基本UTF-8で正常に送られます。古いメーラーで化ける報告があった場合は、HTMLメールに切り替えると解消することが多いです。
質問名の変更でコードが壊れる
前述の通り、フォームの質問テキストを変更すると e.namedValues['お名前'] のキーが合わなくなって動かなくなります。質問名を変更したときはコードも必ず更新するか、テスト送信して動作確認する習慣をつけましょう。
ここまでやって思うこと
あのレビューをもらった当時は落ち込みましたが、今となっては「自動返信の価値」を教えてくれたありがたい指摘だったと思っています。自動返信メールがあるかないかで、お客さんの安心感は本当に別次元です。しかも仕組みは、onFormSubmit関数とトリガーひとつで完結。設定は10分で終わります。
フォームを運用している方は、お客さんに指摘される前に、ぜひ今日入れてしまってください。
関連記事
- GASでGmail自動返信を5分で作る最短レシピ
- GASでGmailを差し込みメールでテンプレ化5例
- Googleフォーム予約をカレンダー登録するGAS連携
- フォーム回答から修了証PDFを自動発行GAS
この記事を書いた人:凛
2児2児のママで現役ナース。夜勤明けの細切れ時間を副業GASに投じ、月5〜8万円の副収入を継続中。「看護師でもコードは書ける」を合言葉に、家事育児とプログラミングを両立する等身大の情報を発信しています。掲載コードは構文・API仕様・ロジックを机上で確認したものです。ご利用の際はテスト送信で動作をお確かめください。