4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【0からGASを学ぶ】GASを用いてGoogleフォーム+ドキュメント+メール送信を自動化しよう

Last updated at Posted at 2023-11-30

はじめに

本シリーズでは、GASの始め方や便利な使い方、ビジネス活用まで幅広く解説します。シリーズをひと通り読んでいただければ、あなたもきっとGASマスターになれるはずです。

シリーズの対象者

  • そもそもGASってなんだかわからない
  • GASを学びたいけど何から始めればいいかわからない方
  • GASはわかり始めたけど、もっと活用ができないかと模索している方
  • とにかくGoogleが好き! という方

前回記事

Googleフォームと連携する

では早速始めていきましょう。【0からGASを学ぶ】シリーズの第12回は「GASを用いてGoogleフォーム+ドキュメント+メール送信の自動化をしよう」です。盛りだくさんのように見えますが、これまで学んできたことの組み合わせです。第7回にてスプレッドシート内のデータをもとに、注文書をドキュメントでつくり、PDF変換し、メール送信するということをしました。今回はそのトリガーをGoogleフォームにするというものです。ひとつひとつのサービスをつなぎ合わせるイメージです、楽しんでいきましょう。イメージはこんな感じ!
Qiita012.png

今回は、私が以前受注しました出席管理システムの欠席届フォーム(簡略版) をベースに解説いたします。

今回やること

  1. Googleフォームのフォーム項目をGASで取得する。
  2. Googleドキュメントで作成したテンプレートに1 で取得した値を設定する。
  3. GoogleドキュメントをPDF変換する。
  4. 変換したPDFを添付ファイルとして相手先にメールを送信する。

やることのイメージ

事前準備

Googleフォームを作成

今回の起動元となるフォームを作成していきましょう。どのようなフォームでもよいのですが欠席届フォームっぽく以下のようなフォームを作成しました。

項目名 タイプ 必須
氏名を選択してください。 プルダウン
欠席日を入力してください。 日付
連日にまたがって欠席する場合は、欠席期間の終了日を入力してください。 日付
届出理由を選択してください。 ラジオボタン

参考に私が作成したフォームは以下となります。

欠席届テンプレートの準備

Googleドキュメントで欠席届テンプレートを適当に作成しましょう。どんな様式でも構いませんが上記フォームの値をマッピングさせるため、それを意識して作成してみて下さい。

第7回でもご説明しましたが、この枠で囲った可変文字部がポイントです。

PDF出力場所の作成

「今回やること」にも記載しましたが、途中でGoogleドキュメントをPDF変換するため、その出力先を作成しておきましょう。

IDの取得

欠席届テンプレートPDF出力場所のIDは事前に取得しておきましょう。

試しに一度回答

Googleフォームを作成したら、右上の「プレビュー」ボタンを押下して、一度回答してみましょう。のちほど回答データを取得するためだけなので、どのような回答でも構いません。

プログラム開始

GASエディタを開く

準備したGoogleフォームからコンテナバインド型でGASプログラムを記述していきましょう。Googleフォームからコンテナバインド型のGASを開く場合は、こちらを参考にしてください。では、どんどんいきますよ、ついてきてください。

STEP.1 Googleフォームのフォーム項目をGASで取得する

Qiita012.gs
function Qiita012_formSubmit(e) {
  let itemResponses;
  // フォームの回答をイベントオブジェクトまたはフォーム自身から取得する。
  if (e !== undefined) {
    itemResponses = e.response.getItemResponses();
  } else {
    const wFormRes = FormApp.getActiveForm().getResponses();
    itemResponses =  wFormRes[wFormRes.length-1].getItemResponses();
  }
  console.log(itemResponses);
}
実行結果
18:50:29	お知らせ	実行開始
18:50:31	情報	[ { toString: [Function],
    getItem: [Function],
    setFeedback: [Function],
    setScore: [Function],
    getScore: [Function],
    getFeedback: [Function],
    getResponse: [Function] },
…
  { toString: [Function],
    getItem: [Function],
    setFeedback: [Function],
    setScore: [Function],
    getScore: [Function],
    getFeedback: [Function],
    getResponse: [Function] } ]
18:50:30	お知らせ	実行完了

これだとどんな値がとれているかはわかりませんが、ばっちりとオブジェクトは取得できていますので準備万端です。

STEP.2 Googleドキュメントで作成したテンプレートにSTEP.1で取得した値を設定する。

次に、回答内容をGoogleドキュメントに設定していきましょう。

このSTEP以降の

  1. Googleドキュメント上の可変文字部に値を設定する
  2. GoogleドキュメントをPDF変換する
  3. 作成したPDFをメール送信する

については第7回も併せて参考にしていただけると幸いです。

Qiita012.gs
// Qiita012_欠席届テンプレートファイル
const DOC_TEMPLATE = DriveApp.getFileById('1CMhLZpBcQ9Y_v0X1YzFOyWuBsmOzqaTmG6uDceVsDz8');

function Qiita012_formSubmit(e) {
  let itemResponses;
  // フォームの回答をイベントオブジェクトまたはフォーム自身から取得する。
  if (e !== undefined) {
    itemResponses = e.response.getItemResponses();
  } else {
    const wFormRes = FormApp.getActiveForm().getResponses();
    itemResponses =  wFormRes[wFormRes.length-1].getItemResponses();
  }
  
  // 回答をもとに欠席届を作成する 
  let wFileRtn = createGDoc(itemResponses);
}

function createGDoc(itemResponses) {
  // テンプレートファイルをコピーする
  const wCopyFile = DOC_TEMPLATE.makeCopy()
        , wCopyFileId = wCopyFile.getId()
        , wCopyDoc = DocumentApp.openById(wCopyFileId); // コピーしたファイルをGoogleドキュメントとして開く
  let wCopyDocBody = wCopyDoc.getBody()                 // Googleドキュメント内の本文を取得する
      , today = dayjs.dayjs();
  // 本日の日付を設定する
  wCopyDocBody = wCopyDocBody.replaceText(`{{date}}`, today.format('YYYY年MM月DD日'));
  // 以降はGoogleフォームの回答をマッピングする
  itemResponses.forEach(function(itemResponse){
    switch (itemResponse.getItem().getTitle()) {
      case '氏名を選択してください。':
        wCopyDocBody = wCopyDocBody.replaceText(`{{name}}`, itemResponse.getResponse());
        break;

      case '欠席日を入力してください。':
        dateF = dayjs.dayjs(itemResponse.getResponse()).format('YYYY年MM月DD日');
        break;

      case '連日にまたがって欠席する場合は、欠席期間の終了日を入力してください。': // 欠席の場合のみ対応
        if ( itemResponse.getResponse()!='' ) {
          dateT = dayjs.dayjs(itemResponse.getResponse()).format('YYYY年MM月DD日');
        } else {
          dateT = dateF;
        }
        wCopyDocBody = wCopyDocBody.replaceText(`{{applydatefrom}}`, dateF);
        wCopyDocBody = wCopyDocBody.replaceText(`{{applydateto}}`, dateT);
        break;

      case '届出理由を選択してください。':
        wCopyDocBody = wCopyDocBody.replaceText(`{{reason}}`, itemResponse.getResponse());
        break;

      default:
        break;
    }
  });
  wCopyDoc.saveAndClose();
  // ファイル名を変更する
  let fileName = '欠席届_'+today.format('YYYYMMDD');
  wCopyFile.setName(fileName);
  // コピーしたファイルIDとファイル名を返却する(あとでこのIDをもとにPDFに変換するため)
  return [wCopyFileId, fileName];
}

これを実行すると、作成した欠席届テンプレートと同階層に値が設定された欠席届が作成されます。ゴールはもうすぐそこですね。

ここでのポイントは第7回ではスプレッドシートの値をループさせながら可変文字部を変更していきましたが、今回はGoogleフォームの値をもとにするため、以下のようにフォームの項目名を判断しながら、対象となる個所を変更することです。

  itemResponses.forEach(function(itemResponse){
    switch (itemResponse.getItem().getTitle()) {
      case '氏名を選択してください。':
        wCopyDocBody = wCopyDocBody.replaceText(`{{name}}`, itemResponse.getResponse());
        break;
//
    }
  });

また何気なく使用しましたが、dayjs.dayjs()と記載している箇所があります。こちら、GASで使用できる日付操作ライブラリとなっており、非常に強力で柔軟なライブラリとなっています。日付操作を行う際は、ぜひお使いください。

dayjsライブラリを追加する場合は、GASエディタの左メニューよりライブラリ横の「+」をクリックし、出てきたダイアログのスクリプトIDに以下のIDを入力してください。

1ShsRhHc8tgPy5wGOzUvgEhOedJUQD53m-gd8lG2MOgs-dXC_aCZn9lFB

そのまま「追加」をクリックすればGAS上で使用できるようになります。

STEP.3 GoogleドキュメントをPDF変換する。

こちらは、第7回とまるっきり一緒ですので、再掲だけしておきます。

createPdf
function createPdf(docId, fileName){
  // PDF変換するためのベースURLを作成する
  let wUrl = `https://docs.google.com/document/d/${docId}/export?exportFormat=pdf`;

  // headersにアクセストークンを格納する
  let wOtions = {
    headers: {
      'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`
    }
  }; 
  // PDFを作成する
  let wBlob = UrlFetchApp.fetch(wUrl, wOtions).getBlob().setName(fileName + '.pdf');

  //PDFを指定したフォルダに保存する
  return PDF_OUTDIR.createFile(wBlob).getId();
}

STEP.4 変換したPDFを添付ファイルとして相手先にメールを送信する。

こちらは、神回で学んだ限界突破方式のメール送信を使いましょう。

sendEmailEx
function sendEmailEx(_recipient, _subject, _body, _option) {
  // 引数の内容でメールを下書き保存する
  const mailDraft = GmailApp.createDraft(_recipient, _subject, _body, _option);
  // 下書き保存したメールIDから下書きを取得し、メール送信を依頼する
  GmailApp.getDraft(mailDraft.getId()).send();
}

結論 こんな感じのプログラムができました

Qiita012.gs
// Qiita012_欠席届テンプレートファイル
const DOC_TEMPLATE = DriveApp.getFileById('1CMhLZpBcQ9Y_v0X1YzFOyWuBsmOzqaTmG6uDceVsDz8');

// PDF出力先
const PDF_OUTDIR = DriveApp.getFolderById('1LSyUSpoHP8mMCyPIwgmy7QwKCQ_KQJkT');

function Qiita012_formSubmit(e) {
  let itemResponses;
  // フォームの回答をイベントオブジェクトまたはフォーム自身から取得する。
  if (e !== undefined) {
    itemResponses = e.response.getItemResponses();
  } else {
    const wFormRes = FormApp.getActiveForm().getResponses();
    itemResponses =  wFormRes[wFormRes.length-1].getItemResponses();
  }

  // 回答をもとに欠席届を作成する 
  let wFileRtn = createGDoc(itemResponses);
  // PDF変換してファイルIDを取得する
  let wPdfId = createPdf(wFileRtn[0], wFileRtn[1]);
  // PDF変換したあとは元ファイルを削除する
  DriveApp.getFileById(wFileRtn[0]).setTrashed(true);
  
  // 今回はPDFファイルを添付してメールを送信する
  sendEmailEx(
    '***************@gmail.com'
    , '【自動送信メール】欠席届の送信'
    , `受講生より欠席届が送信されました。`
    , {attachments: DriveApp.getFileById(wPdfId).getBlob()}
  );
}

function createGDoc(itemResponses) {
  // テンプレートファイルをコピーする
  const wCopyFile = DOC_TEMPLATE.makeCopy()
        , wCopyFileId = wCopyFile.getId()
        , wCopyDoc = DocumentApp.openById(wCopyFileId); // コピーしたファイルをGoogleドキュメントとして開く
  let wCopyDocBody = wCopyDoc.getBody()                 // Googleドキュメント内の本文を取得する
      , today = dayjs.dayjs();
  // 本日の日付を設定する
  wCopyDocBody = wCopyDocBody.replaceText(`{{date}}`, today.format('YYYY年MM月DD日'));
  // 以降はGoogleフォームの回答をマッピングする
  itemResponses.forEach(function(itemResponse){
    switch (itemResponse.getItem().getTitle()) {
      case '氏名を選択してください。':
        wCopyDocBody = wCopyDocBody.replaceText(`{{name}}`, itemResponse.getResponse());
        break;

      case '欠席日を入力してください。':
        dateF = dayjs.dayjs(itemResponse.getResponse()).format('YYYY年MM月DD日');
        break;

      case '連日にまたがって欠席する場合は、欠席期間の終了日を入力してください。': // 欠席の場合のみ対応
        if ( itemResponse.getResponse()!='' ) {
          dateT = dayjs.dayjs(itemResponse.getResponse()).format('YYYY年MM月DD日');
        } else {
          dateT = dateF;
        }
        wCopyDocBody = wCopyDocBody.replaceText(`{{applydatefrom}}`, dateF);
        wCopyDocBody = wCopyDocBody.replaceText(`{{applydateto}}`, dateT);
        break;

      case '届出理由を選択してください。':
        wCopyDocBody = wCopyDocBody.replaceText(`{{reason}}`, itemResponse.getResponse());
        break;

      default:
        break;
    }
  });
  wCopyDoc.saveAndClose();
  // ファイル名を変更する
  let fileName = '欠席届_'+today.format('YYYYMMDD');
  wCopyFile.setName(fileName);
  // コピーしたファイルIDとファイル名を返却する(あとでこのIDをもとにPDFに変換するため)
  return [wCopyFileId, fileName];
}

function createPdf(docId, fileName){
  // PDF変換するためのベースURLを作成する
  let wUrl = `https://docs.google.com/document/d/${docId}/export?exportFormat=pdf`;

  // headersにアクセストークンを格納する
  let wOtions = {
    headers: {
      'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`
    }
  }; 
  // PDFを作成する
  let wBlob = UrlFetchApp.fetch(wUrl, wOtions).getBlob().setName(fileName + '.pdf');

  //PDFを指定したフォルダに保存する
  return PDF_OUTDIR.createFile(wBlob).getId();
}

function sendEmailEx(_recipient, _subject, _body, _option) {
  // 引数の内容でメールを下書き保存する
  const mailDraft = GmailApp.createDraft(_recipient, _subject, _body, _option);
  // 下書き保存したメールIDから下書きを取得し、メール送信を依頼する
  GmailApp.getDraft(mailDraft.getId()).send();
}

おわりに

お疲れ様でした。
第12回は「GASを用いてGoogleフォーム+ドキュメント+メール送信を自動化しよう」ということで、Googleフォームを用いたドキュメント作成の自動化を行ってみました。これによって、実業務でも使えるのではと思った方も多いのではないでしょうか。GoogleフォームやGoogleドキュメントなど、単品で考えると「あぁ便利だな」というレベルに過ぎませんが、組み合わせると「とんでもなく便利!!!」 となります。ぜひ、皆さんも実業務での活用に取り組んでみてください。引き続き、GASを楽しんでいきましょう!!
記事を読んで、「良いな」や「今後に期待できる!」と感じて頂けたらいいねフォローコメントいただけると幸いです。それではまた次回をお楽しみに!

ブログでより詳しく解説しています!

以下画像をクリックしてブログにアクセス!!

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?