GASでGoogleフォーム回答を自動処理する方法|自動返信・PDF作成・Drive保存まで解説

GAS

Googleフォームに届いた回答を確認し、受付メールを送り、申請書をPDFにしてGoogle Driveへ保存する作業を、毎回手作業で行っていないでしょうか。回答件数が少ないうちは対応できますが、件数が増えると返信漏れやファイル名の間違い、転記ミスが起こりやすくなります。GASでGoogleフォーム回答を自動処理すれば、フォーム送信をきっかけに、自動返信、PDF作成、Drive保存、管理者通知までを一つの流れにまとめられます。初心者でも再現できる設定手順とサンプルコードに加え、権限設定や質問名の不一致など、実務でつまずきやすいポイントも解説します。

蒼宮 ルシア
蒼宮 ルシア

👑フォームの回答を確認して、メールを送って、PDFを保存して……件数が増えると大変ですね。

AI執事
AI執事

🤖フォーム送信トリガーを使えば、回答が届いた直後に一連の処理を自動実行できます。

蒼宮 ルシア
蒼宮 ルシア

👑自動返信だけでなく、回答内容をPDFにして保存することもできるのですか?

AI執事
AI執事

🤖はい。Googleドキュメントのひな形を用意すれば、受付書や申請書も自動作成できます。

GoogleフォームとGASで自動化できること

Googleフォームは、問い合わせ、申込受付、社内申請、アンケートなどに利用できます。しかし、回答後の処理までGoogleフォームだけで完結するわけではありません。

回答を受け取った後に担当者がメールを作成し、申請書を保存し、関係者へ連絡している場合は、その部分が新たな手作業になります。GASを組み合わせると、フォーム送信後の処理まで自動化できます。

今回作成する自動処理の流れ
  1. 利用者がGoogleフォームを送信する
  2. 回答がGoogleスプレッドシートに記録される
  3. フォーム送信トリガーがGASを実行する
  4. 回答内容から受付番号を発行する
  5. Googleドキュメントのひな形へ回答内容を差し込む
  6. 完成した文書をPDFへ変換する
  7. 指定したGoogle DriveフォルダへPDFを保存する
  8. 回答者へPDF付きの受付完了メールを送る
  9. 管理者へ申請内容を通知する

Google Apps Scriptには、フォーム回答時に処理を動かすインストール型トリガーがあります。回答先のスプレッドシートに設定するトリガーでは、イベントオブジェクトのnamedValuesから質問名と回答内容を取得できます。

実務で使いやすい場面
業務自動化できる処理期待できる効果
セミナー申込受付メール、参加票PDF、担当者通知返信漏れの防止
社内申請申請書PDF、部署別フォルダ保存ファイル整理の負担軽減
問い合わせ受付受付番号発行、回答者への自動返信初動対応の標準化
見積依頼依頼内容のPDF化、営業担当への通知情報共有の迅速化
点検報告報告書PDF、Drive保存、管理者通知報告書作成時間の削減
蒼宮ルシア
蒼宮ルシア

👑最初から複雑なシステムを目指す必要はありません。まずは自動返信だけを動かし、確認できてからPDF作成や管理者通知を追加すると進めやすいですよ。

自動処理を作る前に準備するもの

今回は、Googleフォーム、回答先スプレッドシート、Googleドキュメント、保存先フォルダの4つを使用します。先に必要なファイルをそろえておくと、GASの設定をスムーズに進められます。

Googleフォームに用意する質問

サンプルコードでは、次の質問名を使用します。

  • 氏名
  • メールアドレス
  • 部署名
  • 申請内容

質問名はサンプルコードの設定と完全に一致させてください。「メールアドレス」と「メールアドレスを入力してください」は、GASでは別の質問名として扱われます。

フォーム側でメールアドレスを収集する設定を使用している場合でも、取得方法や列名がフォームの設定によって変わることがあります。初心者は、最初に「メールアドレス」という記述式の質問を作り、必須回答にしておくと確認しやすくなります。

Googleフォームとスプレッドシートを連携する
  1. Googleフォームを開く
  2. 回答タブを選択する
  3. スプレッドシートにリンクを選択する
  4. 新しいスプレッドシートを作成する
  5. 回答が1行ずつ記録されることを確認する

今回のGASは、Googleフォーム本体ではなく、回答先のスプレッドシートから作成します。フォーム側にもフォーム送信用トリガーがありますが、受け取れるイベントオブジェクトの形式が異なります。サンプルコードをそのまま使う場合は、回答先スプレッドシートに紐づけてください。

PDFのひな形をGoogleドキュメントで作る

Googleドキュメントを新規作成し、次のような差し込み文字を入力します。

申請受付書

受付番号:{{受付番号}}

受付日時:{{受付日時}}

氏名:{{氏名}}

メールアドレス:{{メールアドレス}}

部署名:{{部署名}}

申請内容:{{申請内容}}

二重の波括弧で囲んだ文字が、フォームの回答内容に置き換わります。差し込み文字はサンプルコードのdataに設定する項目名と一致させてください。

PDFを保存するフォルダを作る

Google Driveに「フォーム受付PDF」などのフォルダを作成します。フォルダを開いたときのURLにはフォルダIDが含まれています。

たとえば、URLが「drive.google.com/drive/folders/ABCDEFGHIJK」の場合、ABCDEFGHIJKにあたる部分がフォルダIDです。同じように、GoogleドキュメントのURLからテンプレートIDも確認しておきます。

GASのサンプルコード

回答先スプレッドシートを開き、拡張機能からApps Scriptを選択します。最初から入力されているコードを削除し、次のコードを貼り付けてください。

CONFIG内のテンプレートID、保存先フォルダID、管理者メールアドレスは、自分の環境に合わせて書き換えます。

const CONFIG = {

templateId: ‘ここにGoogleドキュメントのID’,

folderId: ‘ここに保存先フォルダのID’,

adminEmail: ‘管理者のメールアドレス’,

questions: {

name: ‘氏名’,

email: ‘メールアドレス’,

department: ‘部署名’,

details: ‘申請内容’

}

};

function onFormSubmit(e) {

if (!e || !e.namedValues) {

throw new Error(‘フォーム送信トリガーから実行してください。’);

}

const values = e.namedValues;

const now = new Date();

const dateText = Utilities.formatDate(

now,

Session.getScriptTimeZone(),

‘yyyyMMdd-HHmmss’

);

const data = {

受付番号: ‘REQ-‘ + dateText + ‘-‘ + Utilities.getUuid().slice(0, 8),

受付日時: Utilities.formatDate(

now,

Session.getScriptTimeZone(),

‘yyyy/MM/dd HH:mm:ss’

),

氏名: getFirstValue(values, CONFIG.questions.name),

メールアドレス: getFirstValue(values, CONFIG.questions.email),

部署名: getFirstValue(values, CONFIG.questions.department),

申請内容: getFirstValue(values, CONFIG.questions.details)

};

if (!data.メールアドレス) {

throw new Error(‘メールアドレスを取得できませんでした。’);

}

const pdfBlob = createPdf(data);

sendUserMail(data, pdfBlob);

if (CONFIG.adminEmail) {

sendAdminMail(data, pdfBlob);

}

}

function getFirstValue(namedValues, questionName) {

const answer = namedValues[questionName];

if (!answer) {

return ”;

}

if (Array.isArray(answer)) {

return String(answer[0] || ”).trim();

}

return String(answer).trim();

}

function createPdf(data) {

const templateFile = DriveApp.getFileById(CONFIG.templateId);

const fileName =

‘受付書_’ + data.受付番号 + ‘_’ + sanitizeFileName(data.氏名);

const copiedFile = templateFile.makeCopy(fileName);

const document = DocumentApp.openById(copiedFile.getId());

const body = document.getBody();

Object.keys(data).forEach(function(key) {

const searchText = ‘\\{\\{‘ + key + ‘\\}\\}’;

body.replaceText(searchText, String(data[key] || ”));

});

document.saveAndClose();

const pdfBlob = copiedFile

.getBlob()

.getAs(MimeType.PDF)

.setName(fileName + ‘.pdf’);

const folder = DriveApp.getFolderById(CONFIG.folderId);

const pdfFile = folder.createFile(pdfBlob);

copiedFile.setTrashed(true);

return pdfFile.getBlob().setName(pdfFile.getName());

}

function sendUserMail(data, pdfBlob) {

const subject = ‘【受付完了】受付番号 ‘ + data.受付番号;

const body =

data.氏名 + ‘ 様\n\n’ +

‘お申し込みを受け付けました。\n’ +

‘受付番号:’ + data.受付番号 + ‘\n’ +

‘受付日時:’ + data.受付日時 + ‘\n\n’ +

‘受付内容をPDFにして添付しています。\n’ +

‘内容をご確認ください。’;

MailApp.sendEmail({

to: data.メールアドレス,

subject: subject,

body: body,

attachments: [pdfBlob],

name: ‘申請受付窓口’

});

}

function sendAdminMail(data, pdfBlob) {

const subject = ‘【新規受付】’ + data.受付番号;

const body =

‘新しいフォーム回答が届きました。\n\n’ +

‘受付番号:’ + data.受付番号 + ‘\n’ +

‘氏名:’ + data.氏名 + ‘\n’ +

‘メールアドレス:’ + data.メールアドレス + ‘\n’ +

‘部署名:’ + data.部署名 + ‘\n’ +

‘申請内容:’ + data.申請内容;

MailApp.sendEmail({

to: CONFIG.adminEmail,

subject: subject,

body: body,

attachments: [pdfBlob],

name: ‘フォーム自動受付’

});

}

function sanitizeFileName(value) {

return String(value || ‘氏名未入力’)

.replace(/[\\/:*?”<>|]/g, ‘_’)

.slice(0, 50);

}

MailAppは、Apps Scriptからメールを送信するためのサービスです。件名、本文、宛先に加えて、PDFなどのファイルを添付できます。送信時にはGoogleアカウントによる承認が必要です。

DocumentAppではGoogleドキュメントを開いて内容を書き換えられ、DriveAppではファイルのコピー、PDF保存、フォルダへの格納などを行えます。

コード内で変更する場所
設定項目入力する内容注意点
templateIdGoogleドキュメントのID編集権限のあるファイルを指定する
folderIdPDF保存先フォルダのIDスクリプト実行者が保存できるフォルダを指定する
adminEmail管理者のメールアドレス管理者通知が不要なら空文字にする
questionsGoogleフォームの質問名空白や記号を含めて完全に一致させる
一時的なGoogleドキュメントを残したい場合

サンプルコードは、PDFを作成した後にコピー元となった一時ドキュメントをゴミ箱へ移動します。編集可能なGoogleドキュメントも残したい場合は、次の処理を削除してください。

copiedFile.setTrashed(true);

ただし、フォーム回答が増えるほどGoogleドキュメントも増えるため、保存ルールを決めずに残すとDrive内が整理しにくくなります。PDFだけでよい業務では、一時ファイルを削除する運用が向いています。

蒼宮ルシア
蒼宮ルシア

👑テンプレートは直接編集せず、毎回コピーしてから回答内容を差し込みます。元のひな形を残せるため、次の申請にも同じレイアウトを使えます。

フォーム送信トリガーを設定する方法

コードを貼り付けただけでは、フォーム回答時に自動実行されません。Apps Scriptの画面からインストール型トリガーを設定します。

  1. Apps Scriptの左側メニューからトリガーを選択する
  2. 画面右下のトリガーを追加を選択する
  3. 実行する関数にonFormSubmitを指定する
  4. イベントのソースにスプレッドシートからを指定する
  5. イベントの種類にフォーム送信時を指定する
  6. エラー通知の設定を確認する
  7. 保存を選択する
  8. Googleアカウントの権限を承認する

インストール型トリガーは、トリガーを作成したGoogleアカウントの権限で実行されます。そのため、フォーム回答者ではなく、トリガー作成者のアカウントからメール送信やDrive保存が行われます。

コードエディタから直接実行しない

onFormSubmit関数は、フォーム送信時に渡されるイベントオブジェクトを利用します。Apps Scriptの実行ボタンから直接動かすと、eやnamedValuesが存在しないためエラーになります。

動作確認は、実際のGoogleフォームにテスト回答を入力して送信してください。自分のメールアドレスを入力しておけば、自動返信メールとPDF添付の両方を確認できます。

初回のテストで確認する項目
  • 回答先スプレッドシートに新しい行が追加されているか
  • 回答者へ受付完了メールが届いているか
  • 管理者へ通知メールが届いているか
  • メールにPDFが添付されているか
  • 指定したDriveフォルダにPDFが保存されているか
  • PDF内の差し込み文字が回答内容に置き換わっているか
  • 受付番号とファイル名が重複していないか

コードの仕組みを初心者向けに解説

e.namedValuesで回答内容を取得する

フォーム送信時のイベントオブジェクトには、回答情報が含まれています。回答先スプレッドシートのフォーム送信トリガーでは、namedValuesを利用して質問名ごとの回答を取得できます。

たとえば、Googleフォームに「氏名」という質問がある場合、namedValuesの「氏名」から回答を取り出します。

氏名: getFirstValue(values, CONFIG.questions.name)

質問名をCONFIGへまとめているため、フォームの質問名を変更した場合も、コード全体を探さず設定部分だけを修正できます。

受付番号を自動発行する

受付番号は、送信日時とランダムな文字列を組み合わせて作成しています。

REQ-20260729-213700-a1b2c3d4

日時だけでは、同じ秒に複数の回答が届いた場合に番号が重複する可能性があります。ランダムな文字列を付けることで、重複しにくい受付番号にしています。

ひな形の文字を回答内容へ置き換える

Object.keysを使い、dataに登録された項目を順番に処理します。Googleドキュメント内の「{{氏名}}」や「{{申請内容}}」を探し、フォーム回答へ置き換えます。

新しい項目を追加するときは、Googleフォーム、CONFIG、data、Googleドキュメントの差し込み文字をそろえて変更します。どこか一つだけ変更すると、空欄や差し込み文字の残存につながります。

PDFを作成してDriveへ保存する

Googleドキュメントのひな形をコピーし、回答内容を差し込んだ後にPDFへ変換します。完成したPDFは、CONFIGで指定したフォルダへ保存されます。

ファイル名には受付番号と氏名を使用しています。受付番号だけでは誰のファイルか確認しにくく、氏名だけでは同姓同名や複数申請を区別しにくいため、両方を含める設計です。

回答者と管理者へ別々のメールを送る

回答者には受付完了を伝える簡潔なメールを送り、管理者には申請内容を含めた通知を送ります。同じ文章を全員へ送るのではなく、受信者の目的に合わせて内容を分けています。

回答者向けメールに社内管理情報や担当者用メモを含めないように注意してください。自動送信では、宛先と本文を人が送信前に確認できないため、公開してよい情報だけを記載します。

蒼宮ルシア
蒼宮ルシア

👑自動化では、処理を動かすことだけでなく、誰にどの情報を送るかを分けることも大切です。回答者向けと管理者向けの文章は別々に管理しましょう。

実務で失敗しやすいポイントと対処法

メールアドレスを取得できない

最も多い原因は、フォームの質問名とCONFIGの設定が一致していないことです。全角と半角、末尾の空白、記号の有無も確認してください。

フォームの質問名コードの設定結果
メールアドレスメールアドレス取得できる
メールアドレスを入力メールアドレス取得できない
メールアドレスメールアドレス末尾の空白により取得できない場合がある
PDF内に差し込み文字が残る

Googleドキュメントの差し込み文字とdataの項目名を確認します。「{{受付日時}}」と「{{受付日}}」のように名称が違うと置換されません。

文字の途中に装飾を設定すると、Googleドキュメント内部で文字列が分割され、置換できないことがあります。差し込み文字は一度に入力し、文字列全体へ同じ書式を設定してください。

権限エラーが表示される

トリガーを作成したアカウントが、テンプレートファイルや保存先フォルダへアクセスできるか確認します。他人が所有するファイルや共有ドライブを使用する場合は、組織の共有設定やGoogle Workspace管理者の制限も影響します。

DriveAppはGoogle Driveのファイルやフォルダを操作できますが、共有ドライブを含む高度な操作では、Advanced Drive serviceが必要になる場合があります。

メールが2通以上送られる

同じ関数に複数のフォーム送信トリガーが設定されている可能性があります。Apps Scriptのトリガー画面を開き、onFormSubmitが重複して登録されていないか確認してください。

担当者が変わるたびに新しいトリガーを作成すると、複数アカウントから同じ処理が実行されることもあります。運用担当者とトリガー所有者を記録しておくと、引き継ぎ時の混乱を防げます。

エラーが起きても画面に表示されない

フォーム送信トリガーはバックグラウンドで動くため、回答者の画面にはスクリプトエラーが表示されません。Apps Scriptの左側メニューにある実行数を開き、失敗した処理とエラーメッセージを確認します。

インストール型トリガーの処理に失敗すると、トリガー作成者へエラー通知が送られることがあります。実行履歴には、どの関数がどの時点で失敗したかが記録されます。

メール送信数の上限に達する

Apps Scriptには、メール送信や各Googleサービスの利用に割り当てと制限があります。上限はアカウントの種類やGoogle側の仕様変更によって異なるため、大量送信を予定している場合は公式情報を確認してください。

今回のコードでは、1件の回答につき回答者と管理者へメールを送るため、通常は2件分の受信者数を使用します。MailApp.getRemainingDailyQuotaを使うと、その日に送信可能な残りの受信者数を確認できます。

実務向けに改善する方法

処理済みステータスを回答シートへ記録する

フォーム回答が届いたかどうかだけでなく、PDF作成やメール送信まで完了したかを確認できる列を用意すると、運用しやすくなります。

  • 未処理
  • 処理中
  • 完了
  • エラー

エラーが起きた回答だけを絞り込み、手動で再処理できるようにすると、すべての回答を確認し直す必要がありません。

部署や申請種別ごとに保存先を分ける

申請件数が増える場合は、一つのフォルダへすべて保存するのではなく、部署、年度、申請種別などで保存先を分けます。

たとえば、「2026年度」「総務部」「備品購入申請」という階層にすると、後からファイルを探しやすくなります。ただし、分岐条件を増やしすぎるとコードの保守が難しくなるため、実際に検索で使う分類だけに絞ります。

メール本文をスプレッドシートで管理する

自動返信文をコード内に直接書くと、文章を変更するたびにGASを編集する必要があります。担当者が文章を頻繁に修正する場合は、件名と本文を設定用スプレッドシートで管理する方法が向いています。

ただし、設定シートを誰でも編集できる状態にすると、誤操作でメール内容が変わる可能性があります。編集権限を担当者に限定し、変更履歴を確認できるようにしてください。

個人情報を必要以上に保存しない

フォームには、氏名、メールアドレス、電話番号、住所などが入力される場合があります。業務に不要な情報まで収集すると、管理対象が増えます。

  • フォームでは必要な項目だけを収集する
  • 保存先フォルダの共有範囲を限定する
  • 管理者通知へ不要な個人情報を記載しない
  • 保管期間を決め、不要になったファイルを整理する
  • テスト時は実在する顧客情報を使用しない

AIにエラー内容を相談する場合も、メールアドレス、氏名、フォーム回答、ファイルIDなどをそのまま入力しないようにします。必要な部分だけを匿名化して共有してください。

蒼宮ルシア
蒼宮ルシア

👑自動化すると大量の情報を扱えるようになりますが、保存する情報まで増やす必要はありません。必要最小限のデータで運用するほうが管理しやすくなります。

GASによる自動処理が向いている人

向いているケース
  • Googleフォームをすでに業務で利用している
  • 毎回ほぼ同じ内容の受付メールを送っている
  • 回答内容をPDFとして保管したい
  • 月数件から数百件程度の受付を効率化したい
  • Google Workspace内で処理を完結させたい
  • 小さく試してから段階的に改善したい
向いていないケース
  • 大量のメールを一斉送信する必要がある
  • 決済や契約締結など、高度な取引処理が必要である
  • 複数の承認者による複雑なワークフローがある
  • 障害時にも停止できない基幹業務で使用する
  • Google Workspaceの利用が組織内で制限されている
  • 担当者がGASを保守できない

簡単な受付業務や社内申請にはGASが適しています。一方、複雑な承認、厳密なアクセス制御、大量処理、監査ログが必要な業務では、AppSheet、専用のワークフローシステム、クラウドサービスなども比較してください。

人が確認すべき作業と自動化できる作業

作業自動化の可否運用上の考え方
受付番号の発行自動化しやすい一定のルールで機械的に発行する
受付完了メール自動化しやすい固定文と回答内容を組み合わせる
PDF作成と保存自動化しやすいひな形と命名規則を統一する
回答内容の妥当性判断人の確認が必要記載漏れや申請理由を担当者が判断する
申請の承認条件による金額やリスクを含む場合は人が判断する
例外対応人の確認が必要自動処理できない回答を個別対応する

自動化に向いているのは、入力、転記、命名、保存、定型連絡など、判断基準が固定された作業です。申請内容の妥当性、顧客への個別回答、承認判断まで無理に自動化すると、誤った処理がそのまま進む可能性があります。

「自動化する作業」と「人が確認する作業」を分けることで、作業時間を減らしながら品質を保ちやすくなります。

おすすめAIツール

GASの作成や修正では、ChatGPTやGeminiなどの対話型AIを補助として利用できます。エラーメッセージの意味を説明してもらう、コードの各行を初心者向けに解説してもらう、自動返信メールの文章案を作るといった用途に向いています。

AIに任せやすい作業
  • エラーメッセージの一般的な原因を整理する
  • コードの処理内容を日本語で説明する
  • メール件名や本文の下書きを作る
  • 追加したい機能の実装方針を比較する
  • テスト項目の一覧を作る
人が確認するべき作業
  • ファイルIDやフォルダIDが正しいか
  • フォームの質問名がコードと一致しているか
  • 送信先メールアドレスが正しいか
  • 個人情報や社内情報が含まれていないか
  • 実際のGoogleフォームで正常に動くか

AIが生成したコードは、利用しているフォームやGoogle Workspace環境に合わせて動作確認が必要です。最初はテスト用フォームと自分のメールアドレスを使い、本番データを扱う前に一連の処理を確認してください。

よくある質問

Googleフォームだけで自動返信できますか?

フォームの設定によっては回答のコピーを送れますが、自由な件名、受付番号、PDF添付、管理者向けの別メールなどを組み合わせる場合はGASが適しています。

GASの実行ボタンを押すとエラーになるのはなぜですか?

onFormSubmitは、フォーム送信時に渡されるイベント情報を使用するためです。動作確認はコードエディタからではなく、実際のGoogleフォームを送信して行ってください。

Googleフォームの質問を変更しても動きますか?

質問名を変更した場合は、CONFIG内のquestionsも同じ名称へ変更します。質問を削除した場合は、dataやGoogleドキュメントの差し込み文字も見直してください。

PDFではなくGoogleドキュメントで保存できますか?

可能です。サンプルコードのcopiedFile.setTrashed処理を削除すれば、回答内容を差し込んだGoogleドキュメントを残せます。

複数選択の回答も取得できますか?

取得できます。ただし、回答形式によっては複数の値が一つの文字列として渡されます。PDFでの表示方法を確認し、必要に応じて区切り文字や改行へ変換してください。

自動返信メールが迷惑メールに入ることはありますか?

受信側の設定や送信内容によっては迷惑メールとして処理されることがあります。件名を過度に装飾せず、送信者名、受付内容、問い合わせ先を明確にしてください。

大量のフォーム回答にも対応できますか?

一定量までは処理できますが、メール送信数、実行時間、Drive操作などには割り当てがあります。大量処理や停止できない業務では、公式の最新情報を確認し、専用システムも比較してください。

担当者が退職した場合もトリガーは動きますか?

トリガーは作成者のアカウント権限で動きます。アカウントが停止されると処理へ影響する可能性があるため、共有の業務用アカウントや引き継ぎ手順を整えてください。

まとめ

  • Googleフォームの送信トリガーを使うと、回答後の処理を自動実行できる
  • Googleドキュメントのひな形を使えば、回答内容を差し込んだPDFを作成できる
  • PDFのDrive保存、回答者への自動返信、管理者通知を一つの処理にまとめられる
  • 質問名、権限、トリガー、メール送信上限を確認し、テストフォームから導入する

Googleフォーム回答の自動処理は、受付後に行っている定型作業を見直す良いきっかけになります。最初は自動返信だけを設定し、正常に動くことを確認してから、PDF作成やDrive保存を追加すると失敗を減らせます。自動化後も実行履歴を定期的に確認し、人が判断する作業と機械に任せる作業を分けながら運用してください。

タイトルとURLをコピーしました