【第5部】投稿者に自動でPDFをメール送信しよう:Googleフォーム + Apps Script でできる便利な運用

Googleフォームで演題や抄録を集めたあとの運用、皆さんどうしていますか?

「投稿内容を確認してもらうために、PDFをメールで送りたい」
「修正があったら、最新のファイルを再送信したい」
「その記録をスプレッドシートにも残したい」

—— こうしたこと、実は Google Apps Script(GAS)を使えばすべて自動でできます!

このページでは、フォームから投稿された情報を元に作成されたPDFを添付して送信し、その履歴をスプレッドシートに記録する仕組みをご紹介します。

なお、PDF作成までは別の記事で紹介しています。そちらもご参考になさってください。


今回紹介する仕組みでできること

  • 投稿者に自動でPDF付き確認メールを送信
  • 内容が変更された場合には再送信
  • 送信ステータスと送信時刻をスプレッドシートに記録
  • GASのトリガーを使って定期実行にも対応

送信されるメールの文章

実際に送られるメールはこんな内容です:

件名:演題受付完了と登録内容のご確認のお願い【0001YIA】

演題をご登録いただきありがとうございます。
以下の通り、受付番号 【0001YIA】 にて内容を受け付けました。
添付のPDFをご確認いただき、必要に応じてGoogleフォームの編集リンクより修正をお願いします。

ご質問がある場合は、以下の連絡先までお願いいたします。

————
お問い合わせ先:
E-mail: sample.conference.secretary@gmail.com
————
※このメールは自動送信です。


コードの全体(Apps Script)

スプレッドシートの拡張機能 → Apps Script に以下のコードを貼り付けてください。

注意:下記のコードでは、YOUR_FOLDER_ID_HERE には、Google Drive 上で「PDF」という名前のフォルダが含まれている親フォルダのIDを指定してください。
つまり、PDFが保存されるのは「PDF」というサブフォルダであり、その上位にあるフォルダのIDを指定する、というコードとなっています。

function sendAbstractEmails() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('フォームの回答 1');
const data = sheet.getDataRange().getValues();
const header = data[0];

const emailCol = header.findIndex(col => col.toLowerCase().includes("メール"));
const entryCol = header.findIndex(col => col.includes("演題受付番号"));
const timestampCol = header.findIndex(col => col.includes("タイムスタンプ"));
const statusCol = header.findIndex(col => col.includes("送信ステータス"));
const sentTimeCol = header.findIndex(col => col.includes("送信時刻"));

if ([emailCol, entryCol, timestampCol, statusCol, sentTimeCol].includes(-1)) {
SpreadsheetApp.getUi().alert("必要な列が見つかりません。列名をご確認ください。");
return;
}

const parentFolder = DriveApp.getFolderById("YOUR_FOLDER_ID_HERE");
const pdfFolder = parentFolder.getFoldersByName("PDF").next();
const pdfFiles = pdfFolder.getFiles();

const pdfMap = {};
while (pdfFiles.hasNext()) {
const file = pdfFiles.next();
pdfMap[file.getName()] = file;
}

for (let i = 1; i < data.length; i++) {
const row = data[i];
const email = row[emailCol];
const entryId = row[entryCol];
const timestamp = row[timestampCol];
if (!email || !entryId || !timestamp) continue;

const formattedTimestamp = Utilities.formatDate(new Date(timestamp), Session.getScriptTimeZone(), 'yyyyMMdd_HHmmss');
const baseFilename = `${entryId}_abstract_${formattedTimestamp}.pdf`;
const pdfFile = pdfMap[baseFilename];
if (!pdfFile) continue;

const sentStatus = row[statusCol];
const sentTime = row[sentTimeCol];

if (sentStatus === "送信済み" && sentTime) {
const sentTimeStr = Utilities.formatDate(new Date(sentTime), Session.getScriptTimeZone(), 'yyyyMMdd_HHmmss');
if (sentTimeStr === formattedTimestamp) continue;
}

const subject = `演題受付完了と登録内容のご確認のお願い【${entryId}】`;
const body = `演題をご登録いただきありがとうございます。
以下の通り、受付番号【${entryId}】にて内容を受け付けました。
添付のPDFをご確認いただき、必要に応じてGoogleフォームの編集リンクより修正をお願いします。

ご質問がある場合は、以下の連絡先までお願いいたします。

————
お問い合わせ先:
E-mail: sample.conference.secretary@gmail.com
————
※このメールは自動送信です。`;

GmailApp.sendEmail(email, subject, body, {
attachments: [pdfFile.getBlob()],
name: '演題受付システム'
});

sheet.getRange(i + 1, statusCol + 1).setValue("送信済み");
sheet.getRange(i + 1, sentTimeCol + 1).setValue(new Date());

Utilities.sleep(500);
}
}

補足:送信履歴の管理について

このスクリプトは、送信済みかどうか・前回送信時刻をスプレッドシートに記録することで、無駄な再送信を防ぐ仕組みになっています。

投稿内容がGoogleフォームから修正された場合、タイムスタンプが更新されて再送信されます。


送信が必要な条件(メールを送る)

送信ステータスが空欄または “送信済み” 以外
→ 初回送信(まだ送ってない)

送信ステータスが “送信済み” でも、
タイムスタンプ(フォームの送信日時) > 送信時刻(AppScriptで記録)
→ フォーム内容が修正された → 再送信が必要


逆に、メール送信 しない条件(continue でスキップ)

if (!needsSend) continue;

以下の両方が成立していれば、メールは送られません:

  • タイムスタンプ(フォームの修正時刻)≦ 送信時刻(すでに送信済み)


自動実行したいときは「トリガー」を設定

スクリプトエディタの左メニューから「トリガー」アイコン(時計マーク)をクリック
関数 sendAbstractEmails を選択
「時間主導型」→「毎時」などに設定すれば定期チェックが可能です


まとめ

Googleフォームで投稿を集めたあと、PDFを添付して自動でメール送信!

送信ステータスや時刻も記録して再送信制御

トリガー+Apps Script でフォーム運用がスマートに!

トリガーの設定については、また後日のご紹介を予定しています。

コメント

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