Document

[AdvancedGFormsフォームの作り方]メールの送信設定

多くの場合、お問い合わせなどフォームからのアクションがあったらユーザーに対してのサンクスメールや管理者に対してのお問い合わせがあったことをお知らせするメールなどを送信したいですよね。

ですが、残念な事に通常、GoogleFormsではデフォルトメールしか送信する事ができません。

メールの内容は変える事ができないのでGoolgeFormsのメール送信機能は実用的ではないのです…

でも大丈夫!

GoogleFormsをスプレッドシートと連携し、スプレッドーシートからオリジナルのメールを送信する事が可能です。

ここではスプレッドーシートからオリジナルメールを送信する方法について解説します。

メール送信の概要

AdvancedGFormsで製作したお問い合わせフォームから送信アクションが起こり、ユーザーの手元にメールが届くまでの流れは以下になります。

  1. ユーザーがwebサイトからフォームを送信する
  2. GoogleFormsで製作したフォームへデータが送信される
  3. GoogleFormsと連携しているスプレッドシートに送信データが反映される
  4. スプレッドシートがデータの追加を検知し、GASを実行する
  5. GASのプログラムからメールを送信する

このように少しステップは多いですが、メールを送信する事が可能です。

この記事ではメールを送信するのに必要なGASプログラムも共有します。

GASをカスタマイズする事で、ユーザーが送信した内容によってメールのメッセージを振り分けたり、メール以外にもさまざまが外部連携なども行えます。

スプレッドシートのテンプレートをコピーする

メールの送信はメール本文の設定やメールのタイトルなど、必要な設定がいくつか存在します。

一般的に設定が必要な箇所をプログラムを触る事なく簡単に設定できるよう、スプレッドシートのテンプレートを用意していますのでそのテンプレートを複製し、メール送信の設定を行っていきます。

AdvancedGFormsテンプレート

👆のシートを開き、コピーを製作しましょう。

コピーの製作はシート左上のファイル->コピーを作成をクリックします。

すると、このようなモーダルが開きますので名前を適切なものに変更してコピーを作成ボタンをクリックします。

今回は「webサイトのお問い合わせフォーム」という名前を付け、コピーを製作しました。

次の説明でこのシートとGoogleFormsで製作したフォームを紐づけていきます。

GoogleFormsで製作したフォームとスプレッドシートを連携する

こちらの例ではAdvancedGForms用のGoolgeFormsの作り方で製作したフォームと連携させながら解説していきます。

まず、 製作したGoolgeフォームを開きます。

開くと「質問」とタブが開いていると思いますので、「回答」のタブをクリックし開きましょう。

「回答」タブを開きましたらその中の「スプレッドシートにリンク」をクリックします。

クリックすると以下のようなモーダルが表示されますので「既存のスプレッドシートを選択」をチェックし、選択ボタンを押します。

先ほど製作したスプレッドーシートを選択し連携しましょう。

連携をすると、自動的に連携先のスプレッドーシートが開きます。

「フォームの回答1」というシートが追加されおり、Googleフォームでキャッチしたお問い合わせデータはこちらのシートに記録されていきます。

こちにたまったデータをメール送信プログラムで使用するために連携して自動生成された「フォームの回答1」はdataという名前へ変更します。

シート連携はこちらで完了です。

メール送信を行うGASプログラムの設定

メールの送信はGAS(Google Apps Script)を使用して行います。

GAS(Google Apps Script)とはGoogleWorkSpaceで使用可能なアプリを開発するためのサービスです。

詳しくは公式サイトをご覧ください。

このGASを使ってメール送信アプリを製作します。

プログラム言語はJavaScriptを使用可能です。

メール送信プログラムの設定手順は以下になります。

  1. Apps Scriptを開く
  2. プログラムを書く
  3. プログラムが起動するタイミングを設定する

Apps Scriptを開く

まずはApps Scriptを開き、アプリを製作するための管理画面を開きます。

Apps Scriptはスプレッドーシートの「拡張機能」→「Apps Script」から開く事ができます。

Apps Scriptをクリックすると、以下のようなページが別タブで開きます。

プログラムを書く

次にメール送信用のJavaScriptを記載してきます。

プログラムは以下に記載していますので、こちらのコードを「コード.gs」に貼り付けましょう。


function main() {
    const userConfigSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('userMailConfig');
    const adminConfigSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('adminMailConfig');

    const config = {
        user: {
            to: userConfigSheet.getRange('B1').getValue(),
            senderAddress: userConfigSheet.getRange('B2').getValue(),
            senderName: userConfigSheet.getRange('B3').getValue(),
            subject: userConfigSheet.getRange('B4').getValue(),
            replyTo: userConfigSheet.getRange('B5').getValue(),
            body: userConfigSheet.getRange('B6').getValue()
        },
        admin: {
            to: adminConfigSheet.getRange('B1').getValue(),
            cc: adminConfigSheet.getRange('B2').getValue(),
            bcc: adminConfigSheet.getRange('B3').getValue(),
            senderAddress: adminConfigSheet.getRange('B4').getValue(),
            senderName: adminConfigSheet.getRange('B5').getValue(),
            subject: adminConfigSheet.getRange('B6').getValue(),
            replyTo: adminConfigSheet.getRange('B7').getValue(),
            body: adminConfigSheet.getRange('B8').getValue()
        }
    };

    const dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('data');
    const rows = dataSheet.getLastRow();
    const cols = dataSheet.getLastColumn();
    const rg = dataSheet.getDataRange();

    for (let i = 1; i <= cols; i++) {
        let col_name = rg.getCell(1, i).getValue();
        let col_value = rg.getCell(rows, i).getValue();

        if(col_name == 'タイムスタンプ' || i == 1) continue;

        config.user.to = config.user.to.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
        config.user.senderAddress = config.user.senderAddress.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
        config.user.subject = config.user.subject.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
        config.user.replyTo = config.user.replyTo.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
        config.user.body = config.user.body.replace(new RegExp(`{${col_name}}`, 'g'), col_value);

        config.admin.subject = config.admin.subject.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
        config.admin.replyTo = config.admin.replyTo.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
        config.admin.body = config.admin.body.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    };

    /**
     * ユーザーへの送信処理
     */
    if (config.user.to) {
        const userOptions = {
            name: config.user.senderName,
            replyTo: config.user.replyTo
        };

        if(config.user.senderAddress) userOptions.from = config.user.senderAddress;

        try{
            GmailApp.sendEmail(config.user.to, config.user.subject, config.user.body, userOptions);
        } catch(e){
            writeLogToSpreadsheet(`user mail send error: ${e.message}`);
            return;
        };
    };

    /**
     * 管理者への送信処理
     */
    if (config.admin.to) {
        const adminOptions = {
            name: config.admin.senderName,
            replyTo: config.admin.replyTo,
        };

        if (config.admin.cc) adminOptions.cc = config.admin.cc;
        if (config.admin.bcc) adminOptions.bcc= config.admin.bcc;
        if (config.admin.senderAddress) adminOptions.from = config.admin.senderAddress;

        try{
            GmailApp.sendEmail(config.admin.to, config.admin.subject, config.admin.body, adminOptions);
        } catch(e){
            writeLogToSpreadsheet(`admin mail send error: ${e.message}`);
            return;
        }
    }

    writeLogToSpreadsheet(`success to send mail: ${config.user.to}`);
}

/**
 * スプレッドシートへログを書き込みます
*/
function writeLogToSpreadsheet(msg) {
    const sheetName = "log";

    const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    const sheet = spreadsheet.getSheetByName(sheetName);

    sheet.appendRow([new Date(), msg]);
}

元から記載されている「myFunction」は消して大丈夫です。

フロッピーのアイコンをクリックして保存し、アプリ名をわかりやすい名前に変更します。

プログラムが起動するタイミングを設定する

先ほど製作したメール送信プログラムを起動させるタイミングを設定してきます。

左側に折りたたまれたメニューの中のストップウォッチのようなアイコンをクリックし、「トリガー」という項目を開きます。

ページを開くと、右下に「トリガーを追加」というボタンがありますのでこちらをクリックします。

モーダルが開きますので、こちらの「イベントの種類を選択」をフォーム送信時に設定し「エラー通知設定」を今すぐ通知を受け取るに設定し、右下の保存ボタンで保存します。

保存ボタンを押すと以下のようなモーダルが表示されますのでメール送信で使用するGoogleアカウントを選択します。

※こちらで選択したアカウントがメール送信時の送信元情報に表示されるわけではありませんのでご安心ください。送信元情報に表示される名前やメールアドレスは次のセクションで設定します。

↓のような画面が開きますので、「Advanced」をクリックします。

「Advanced」をクリックすると↓のような項目が表示されますので、こちらの「Go to 無題のプロジェクト…」をクリックします。

↓のような画面に切り替わりますので「Allow」をクリックする事でトリガーの設定が完了します。

メールの送信内容の設定を行う

最後にメールの送信内容の設定を行いましょう。

メールの送信内容とは、メール本文や、メール送信の際に使用される送信元の情報などです。

メールの送信内容はテンプレートをコピーして製作したスプレッドシートから簡単に設定をする事ができます。

メール送信に必要な設定項目とは?

設定をしていく前にそもそもメール送信する上で設定が必要な項目ってなに?

という方もいると思いますので先にこちらを説明します。

メール送信に必要な設定の項目は以下になります。

  1. 送信先メールアドレス
  2. cc, bcc
  3. 送信元メールアドレス
  4. 送信元名
  5. 件名
  6. 返信先メールアドレス
  7. 本文

イメージが付きにくいかもしれませんので、以下に例を出します。

Gメールでメールを受信した場合、設定した項目は以下のように表示されます。

そして、多くの場合、メールの送信はお問い合わせを行ってきたユーザーに対いてのお礼メールとお問い合わせがあったことを管理者へお知らせするメールの2つが存在しますので上記で上げた設定を2セット行います。

スプレッドシートからメール送信内容の設定を行います

それぞれの設定項目の説明は以下になります。

①送信先メールアドレス共通送信先のメールアドレスを記入します。
ユーザーへのメールの場合はお問い合わせしてきた
ユーザーのメールアドレスになりますので変数を使用し
ユーザーのメールアドレスが動的に入るよう設定します。
②cc, bcc管理者のみ通常のcc, bccの仕様と同じで、
メールを複数の宛先に送信可能です。
カンマ区切りでメールアドレスを設定する事で
複数のメールアドレスを設定する事が可能です。
③送信元メールアドレス共通送信元のメールドレスを設定します。
空白にする事で自動的にこのGASを製作した
Googleアカウントのメールアドレスが適応されます。

※こちらに設定できるメールアドレスはこのGASを製作した
Googleアカウントのエイリアスとして登録されている
メールアドレスのみです。別のメールアドレスを設定する
場合は設定したいメールアドレスをエイリアスとして
登録する作業が必要になります。
詳しくはこちらの記事を確認してください。
④送信元名共通送信した人の名前を設定します。
⑤件名共通メールの件名を設定します。
⑥返信先メールアドレス共通返信先のメールアドレスを設定します。
設定する事で、メールソフトで「返信」のボタンを押すと
こちらに設定されたメールアドレス宛に返信用の
メールが生成されます。

管理者向けのメールにはこちらの項目は変数を使用して
ユーザーのメールを設定すると返信作業がボタン1つで
完了するので楽になります。
⑦本文共通メールの本文を設定します。
HTMLメールは使用できません。
変数が使用可能ですのでお問い合わせ内容の値を動的に
反映しメールの本文を製作する事が可能です。

まずはユーザー向けのメール設定を行いましょう。

スプレッドシートの「userMailConfig」シートを開きます。

設定には変数を使用して送信されたフォームのデータを埋め込む事が可能です。

変数はGoogleFormsでフォームを製作した際に使用した質問のラベル名を{}で囲います。

質問のラベル名はフォームを連携した際に自動生成されたdataシートからも確認が可能です。

設定が完了したら同じように「adminMailConfig」シートも開き、管理者向に送信するメールの設定を行います。

adminMailConfigシートには、userMailConfigの設定項目にプラスしてcc,bccという項目があります。

cc,bccの項目は通常のメールのcc,bccと同じで、このメールを複数の人へ一斉送信が可能です。

cc, bccに複数人のメールアドレスを設定したければカンマ区切りで設定する事で可能となります。

こちらでメール送信に必要な設定は完了です。

実際にフォームから送信テストを行い、スプレッドシートにデータが記録され、メールも無事届くことを確認しましょう。

logシートについて

製作したスプレッドシートには「log」というシートがありますが、こちらは送信がうまくいったのか、失敗したのかログが記録されていきます。

メール送信プログラムの解説

メール送信のプログラムはJavaScriptで記載されております。

内容をカスタマイズしてさらに高度な連携やメール送信機能などを製作可能ですのでその助けになるよう、プログラムの解説を行います。

const userConfigSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('userMailConfig');
const adminConfigSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('adminMailConfig');

こちらの2行でメールの送信内容を記載したシートを取得しています。

このシートに記載された情報を読み取り、それぞれの情報をメール送信プログラムへセットしています。

SpreadsheetAppオブジェクトはGASが用意しているもので、このオブジェクトにスプレッドシートを操作するための処理がまとめて入っています。

[公式]Class SpreadsheetAppリファレンス

const config = {
    user: {
        to: userConfigSheet.getRange('B1').getValue(),
        senderAddress: userConfigSheet.getRange('B2').getValue(),
        senderName: userConfigSheet.getRange('B3').getValue(),
        subject: userConfigSheet.getRange('B4').getValue(),
        replyTo: userConfigSheet.getRange('B5').getValue(),
        body: userConfigSheet.getRange('B6').getValue()
    },
    admin: {
        to: adminConfigSheet.getRange('B1').getValue(),
        cc: adminConfigSheet.getRange('B2').getValue(),
        bcc: adminConfigSheet.getRange('B3').getValue(),
        senderAddress: adminConfigSheet.getRange('B4').getValue(),
        senderName: adminConfigSheet.getRange('B5').getValue(),
        subject: adminConfigSheet.getRange('B6').getValue(),
        replyTo: adminConfigSheet.getRange('B7').getValue(),
        body: adminConfigSheet.getRange('B8').getValue()
    }
};

こちらでメール送信に必要な情報をまとめて保持しています。

getRangeメソッドでセルを指定してメール送信に必要な情報を取得します。

const dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('data');
const rows = dataSheet.getLastRow();
const cols = dataSheet.getLastColumn();
const rg = dataSheet.getDataRange();

フォームから送信された内容を取得し、行、列、データが存在する範囲を取得します。

データが存在する範囲すべてをgetDataRangeで取得し、getLastRowgetLastColumnで取得した最後の行列情報を使って指定する事で一番最新の送信データを取得可能です。

以下のforで送信データの取得処理を行っています。

for (let i = 1; i <= cols; i++) {
    let col_name = rg.getCell(1, i).getValue();
    let col_value = rg.getCell(rows, i).getValue();

    if(col_name == 'タイムスタンプ' || i == 1) continue;

    config.user.to = config.user.to.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    config.user.senderAddress = config.user.senderAddress.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    config.user.subject = config.user.subject.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    config.user.replyTo = config.user.replyTo.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    config.user.body = config.user.body.replace(new RegExp(`{${col_name}}`, 'g'), col_value);

    config.admin.subject = config.admin.subject.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    config.admin.replyTo = config.admin.replyTo.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
    config.admin.body = config.admin.body.replace(new RegExp(`{${col_name}}`, 'g'), col_value);
};

5行目はデータのカラム名がタイムスタンプの場合、もしくは、1列目のカラムを無視していますが、これはGoolgeFormsの仕様でスプレッドシート連携をすると自動的にタイムスタンプの情報がシートの1列目に追加されるためです。

もしもタイムスタンプを使用したい場合はこちらの処理を外して使用するとよいでしょう。

残りは置換処理です。

メール本文の{}で囲われた部分をフォームのラベル名(dataシートのカラム名)で置換しています。

置換処理が終われば後はメールの送信処理になります。

ユーザーと管理者の2者へメールを送信する処理がそれぞれ続きます。

/**
    * ユーザーへの送信処理
    */
if (config.user.to) {
    const userOptions = {
        name: config.user.senderName,
        replyTo: config.user.replyTo
    };

    if(config.user.senderAddress) userOptions.from = config.user.senderAddress;

    try{
        GmailApp.sendEmail(config.user.to, config.user.subject, config.user.body, userOptions);
    } catch(e){
        writeLogToSpreadsheet(`user mail send error: ${e.message}`);
        return;
    };
};

/**
    * 管理者への送信処理
    */
if (config.admin.to) {
    const adminOptions = {
        name: config.admin.senderName,
        replyTo: config.admin.replyTo,
    };

    if (config.admin.cc) adminOptions.cc = config.admin.cc;
    if (config.admin.bcc) adminOptions.cc = config.admin.bcc;
    if (config.admin.senderAddress) adminOptions.from = config.admin.senderAddress;

    try{
        GmailApp.sendEmail(config.admin.to, config.admin.subject, config.admin.body, adminOptions);
    } catch(e){
        writeLogToSpreadsheet(`admin mail send error: ${e.message}`);
        return;
    }
}

残りは管理者向け、ユーザー向けそれぞれのメール送信処理です。

GmailAppオブジェクトもGASが用意しているものです。こちらを使用する事でメールを送信可能です。

[公式]Class MailAppリファレンス

try catchでエラーを検知し、エラーがあった場合はlogシートに送信ログを記録します。

writeLogToSpreadsheet(`success to send mail: ${config.user.to}`);

最後に送信に成功した際にlogシートに送信ログを記録します。