はじめに
本シリーズでは、GASの始め方や便利な使い方、ビジネス活用まで幅広く解説します。シリーズをひと通り読んでいただければ、あなたもきっとGASマスターになれるはずです。
シリーズの対象者
- そもそもGASってなんだかわからない方
- GASを学びたいけど何から始めればいいかわからない方
- GASはわかり始めたけど、もっと活用ができないかと模索している方
- とにかくGoogleが好き! という方
前回記事
Googleフォームと連携する
では早速始めていきましょう。【0からGASを学ぶ】シリーズの第12回は「GASを用いてGoogleフォーム+ドキュメント+メール送信の自動化をしよう」です。盛りだくさんのように見えますが、これまで学んできたことの組み合わせです。第7回にてスプレッドシート内のデータをもとに、注文書をドキュメントでつくり、PDF変換し、メール送信するということをしました。今回はそのトリガーをGoogleフォームにするというものです。ひとつひとつのサービスをつなぎ合わせるイメージです、楽しんでいきましょう。イメージはこんな感じ!
今回は、私が以前受注しました出席管理システムの欠席届フォーム(簡略版) をベースに解説いたします。
今回やること
- Googleフォームのフォーム項目をGASで取得する。
- Googleドキュメントで作成したテンプレートに1 で取得した値を設定する。
- GoogleドキュメントをPDF変換する。
- 変換したPDFを添付ファイルとして相手先にメールを送信する。
やることのイメージ
事前準備
Googleフォームを作成
今回の起動元となるフォームを作成していきましょう。どのようなフォームでもよいのですが欠席届フォームっぽく以下のようなフォームを作成しました。
項目名 | タイプ | 必須 |
---|---|---|
氏名を選択してください。 | プルダウン | 〇 |
欠席日を入力してください。 | 日付 | 〇 |
連日にまたがって欠席する場合は、欠席期間の終了日を入力してください。 | 日付 | |
届出理由を選択してください。 | ラジオボタン | 〇 |
参考に私が作成したフォームは以下となります。
欠席届テンプレートの準備
Googleドキュメントで欠席届テンプレートを適当に作成しましょう。どんな様式でも構いませんが上記フォームの値をマッピングさせるため、それを意識して作成してみて下さい。
第7回でもご説明しましたが、この枠で囲った可変文字部がポイントです。
PDF出力場所の作成
「今回やること」にも記載しましたが、途中でGoogleドキュメントをPDF変換するため、その出力先を作成しておきましょう。
IDの取得
欠席届テンプレート
とPDF出力場所
のIDは事前に取得しておきましょう。
試しに一度回答
Googleフォームを作成したら、右上の「プレビュー」ボタンを押下して、一度回答してみましょう。のちほど回答データを取得するためだけなので、どのような回答でも構いません。
プログラム開始
GASエディタを開く
準備したGoogleフォームからコンテナバインド型でGASプログラムを記述していきましょう。Googleフォームからコンテナバインド型のGASを開く場合は、こちらを参考にしてください。では、どんどんいきますよ、ついてきてください。
STEP.1 Googleフォームのフォーム項目をGASで取得する
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以降の
- Googleドキュメント上の可変文字部に値を設定する
- GoogleドキュメントをPDF変換する
- 作成したPDFをメール送信する
については第7回も併せて参考にしていただけると幸いです。
// 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で使用できる日付操作ライブラリとなっており、非常に強力で柔軟なライブラリとなっています。日付操作を行う際は、ぜひお使いください。
STEP.3 GoogleドキュメントをPDF変換する。
こちらは、第7回とまるっきり一緒ですので、再掲だけしておきます。
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を添付ファイルとして相手先にメールを送信する。
こちらは、神回で学んだ限界突破方式のメール送信を使いましょう。
function sendEmailEx(_recipient, _subject, _body, _option) {
// 引数の内容でメールを下書き保存する
const mailDraft = GmailApp.createDraft(_recipient, _subject, _body, _option);
// 下書き保存したメールIDから下書きを取得し、メール送信を依頼する
GmailApp.getDraft(mailDraft.getId()).send();
}
結論 こんな感じのプログラムができました
// 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を楽しんでいきましょう!!
記事を読んで、「良いな」や「今後に期待できる!」と感じて頂けたらいいねやフォロー、コメントいただけると幸いです。それではまた次回をお楽しみに!