Googleフォームの回答通知を別のメールアドレスへ送りたい場合は、標準の通知で足りるか、任意の宛先へ送る処理が必要かを先に確認します。
標準通知で足りる場合とGASが必要な場合
自分のアカウントで新しい回答を知るだけなら、フォームの「回答」タブのメニューから「新しい回答についてのメール通知を受け取る」を使います。
標準通知の設定についてはGoogleフォーム公式ヘルプで確認できます。
通知先や本文を指定する場合は、フォームに紐付けたGASでメールを送る方法があります。
以下のコードは既存メールを転送する処理ではなく、回答のうち指定した設問だけを通知本文にする処理です。
| 条件 | 結果 |
|---|---|
| 標準の回答通知 | 自分のアカウントで新しい回答を知りたい場合 |
| 本稿のGAS | 許可された1宛先へ、選んだ設問の回答を通知したい場合 |
| 回答先スプレッドシートのGAS | イベントの形式が異なるため、本稿のコードをそのまま使わない |
練習フォームと未送信テストを用意する
本番フォームには追加せず、練習フォームに「ご用件」「希望日」「送信対象外」という短文の設問を用意します。
個人の氏名や連絡先は入力しません。
フォームの編集画面でメニューからスクリプトエディタを開き、Code.gsに次のコードを貼り付けて保存します。
回答先のシートにある「拡張機能→Apps Script」から開いたプロジェクトとは区別してください。
const FORM_MAIL = Object.freeze({
recipient: 'CHANGE_ME',
dryRun: true,
allowedQuestions: ['ご用件', '希望日']
});
function sendFormToEmail(e) {
const message = buildFormNotification(e);
if (FORM_MAIL.dryRun) {
console.log('DRY_RUN: メール未送信。対象設問数=' + message.questionCount);
return;
}
const to = FORM_MAIL.recipient;
if (!/^[^\s,;<>@]+@[^\s,;<>@]+\.[^\s,;<>@]+$/.test(to) ||
/@example\.(?:com|org|net|invalid)$/i.test(to)) {
throw new Error('受信を許可された1宛先へrecipientを設定してください。');
}
if (MailApp.getRemainingDailyQuota() < 1) throw new Error('送信の残り割当がありません。');
MailApp.sendEmail({to: to, subject: message.subject, body: message.body});
console.log('メール送信処理を実行しました。受信側で件数と内容を確認してください。');
}
function buildFormNotification(e) {
if (!e || !e.response || typeof e.response.getItemResponses !== 'function' ||
!e.source || typeof e.source.getTitle !== 'function') {
throw new Error('フォーム由来の送信イベントが必要です。手動実行はtestFormMessageを使ってください。');
}
const responses = e.response.getItemResponses();
if (responses.length > 30) throw new Error('この練習は30設問までです。');
const selected = responses.filter(r => FORM_MAIL.allowedQuestions.includes(r.getItem().getTitle()));
if (!selected.length) throw new Error('許可した設問と実際の設問名が一致しません。');
const body = selected.map(r => {
const value = r.getResponse();
const answer = value === null || value === '' ? '(未回答)' :
Array.isArray(value) ? JSON.stringify(value) : String(value);
return r.getItem().getTitle() + ': ' + answer;
}).join('\n\n');
const subject = String(e.source.getTitle()).replace(/[\r\n]+/g, ' ') + '(回答通知)';
return {subject: subject, body: body, questionCount: selected.length};
}
function testFormMessage() {
const sample = [
{getItem: () => ({getTitle: () => 'ご用件'}), getResponse: () => '資料請求(練習)'},
{getItem: () => ({getTitle: () => '希望日'}), getResponse: () => '2026-10-10'},
{getItem: () => ({getTitle: () => '送信対象外'}), getResponse: () => 'この項目は含めない'}
];
const message = buildFormNotification({
source: {getTitle: () => 'お問い合わせ練習'},
response: {getItemResponses: () => sample}
});
console.log(message.subject + '\n' + message.body);
}
練習コードと模擬テストをダウンロードできます。
コードは初期状態でdryRunがtrueになっており、メールを送りません。
関数の選択欄でtestFormMessageを選んで実行します。
練習用のオブジェクトを使い、「お問い合わせ練習(回答通知)」「ご用件: 資料請求(練習)」「希望日: 2026-10-10」が実行ログに並ぶ想定です。
sendFormToEmailをエディタの実行ボタンで直接動かしても、フォームの回答イベントは渡されません。
この場合は「フォーム由来の送信イベントが必要です」というエラーを出す設計です。
フォーム送信トリガーを設定する
実際のイベントを確かめる段階で、エディタ左側の「トリガー」からトリガーを追加します。
実行する関数はsendFormToEmail、イベントのソースは「フォームから」、イベントの種類は「フォーム送信時」を選びます。
dryRunはtrueのままにします。
表示される権限と実行するアカウントを確認し、同じ関数のトリガーを重複して登録しないでください。
インストール型トリガーは作成者の権限で実行されます。
公式のトリガー仕様も確認してください。
練習フォームから架空の回答を1回送信し、実行履歴でDRY_RUN: メール未送信。対象設問数=2を確認します。
このログには実際の回答本文を出しません。
フォームの送信イベントはe.responseを持ち、シートの送信イベントではe.valuesやe.namedValuesなどを使います。
両者を混ぜると動かないため、イベントオブジェクトの公式仕様で起点を確認します。
受信を確認してから運用する
受信者の同意を確認した1つの宛先をrecipientに設定し、allowedQuestionsを通知に必要な設問名だけにします。
設問名が変わった場合も更新が必要です。
送信確認をする段階でだけdryRunをfalseにします。
練習回答を1回送り、受信側で件名・設問・件数を確認してから運用を開始します。
複数の宛先やexample.comなどの練習用アドレスはコードで拒否します。
メール送信専用のMailAppを使い、送信割当を確認します。
コードが成功しても到着や迷惑メール判定までは保証できないため、受信側の確認を省かないでください。
| 条件 | 結果 |
|---|---|
| イベントのエラー | 手動実行ならtestFormMessageを選ぶ。トリガーなら起点がフォームか確認する |
| 設問名が一致しない | allowedQuestionsとフォームの設問を照合する |
| 通知が2通来る | トリガー一覧で同じ処理の重複を確認する |
| 割当不足・送信失敗 | 実行履歴のエラーを確認し、連続再送しない |
| 処理を止めたい | dryRunをtrueに戻し、自分が追加したトリガーだけ解除する |
検証範囲と関連記事
2026年10月3日時点で、この通知コードはローカルの模擬イベントで確認しました。
実フォームの送信トリガー、MailAppの権限承認、外部宛先への送信と到着確認は未実施です。
Gmailで本文を再利用する場合はメール本文を新しい下書きにコピーする方法、他の作業はGoogleの目的別ガイドから確認できます。
関連記事と旧資料
関連記事は目的が合うものから確認してください。
旧資料や外部ツールの説明は、本稿の練習コード・検証範囲と異なる場合があります。



