GoogleAppsScript
gas
gmail
GoogleDocs
GoogleSpreadSheet

GoogleAppsScriptで複数のGoogleAppsを組みわせて実現したメール配信について


はじめに


概要

就活の面接やキャリアアドバイザーさんとの面談で、「GoogleAppsScriptを使ってメールの自動配信を行ったり、Excelのマクロや関数を駆使して作業の効率化をしていました。」と偉そうなことを言っているが、最近はGoogleAppsScriptに触っていない。

最近になってまた使いそうな予感がするので、学生時代に作ったメールの自動配信プログラムをGoogleAppsScriptで実装してみました。私と一緒に作業をしていた人は「ん?こいつ...」と思うかもしれませんが、過ぎたことなので水に流しましょう^^


仕様

大学生の私は、「一人ひとりに送られている感じがした方が返信率・既読率・イベント参加率が高い」という妄想のもと以下のような仕様を実現しようとしていました。

Bcc使っても誰も見てくんないっしょ!!


  • SpreadSheetに載せた連絡先をもとに一人一人にメール配信を行う。

  • メールの雛形はDocumentから取得する。

  • 宛名は大学名と個人名を使用し、「〇〇大学 〇〇学部 〇〇様」のような形にする。


前提

以下のようなファイルを予め用意します。


SpreadSheet(Contact.sheet)

こんなイメージ

名前
大学
学部
メールアドレス

Kurata
〇〇大学
××学部
~~@△△.com


Document(MailTemplate.document)

${university} ${faculty}

${name} 様

こんにちは。...

よろしくお願いします。


実装


プログラムのイメージ

こんな感じで作れば大丈夫ですね。

1. メールのテンプレートを取得

2. 連絡先を取得

3. 1人ずつ4~5繰り返す

4. メールのテンプレートのプレースホルダを実データに差し替え

5. 作成したメール本文と取得した連絡先をもとにメールを送信


プログラム


メールのテンプレートを取得

Googleドキュメント内の文章を取得する関数です。

/**

* Documentからメールのテンプレートを取得する関数.
* 戻り値の型 String
*/

var getTemplateBody = function(){
const documentId = 'yourTemplateDocumentId';
const document = DocumentApp.openById(documentId);

const body = document.getBody().getText();
return body;
}

コードを見てわかると思いますが、画面上の操作と全く同じことをしています。

ドキュメントを開いて、テキストを取得しているだけです。

個々のオブジェクトとメソッドについては公式ドキュメントをご覧ください。


連絡先を取得

Googleスプレッドシート内に書いてある連絡先を取得する関数です。

RangeオブジェクトからgetValues()メソッドでデータを取得すると2次元配列でデータを取得できます。

ただ、このあと作成するメインの処理で、「表の何列目にどのデータが入っているのか」を気にしながらコードを書きたくなかったので、自分で定義したContactクラスに1行ごとのデータを突っ込んでいます。

/**

* SpreadSheetから連絡先を取得する関数.
* 戻り値の型 Contactクラスの配列
*/

var getContacts = function() {
const spreadsheetId = 'yourSpreadSheetId';
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);

const sheetName= 'シート1';
const sheet = spreadsheet.getSheetByName(sheetName);

const nameColumnIndex = 0;
const universityColumnIndex = 1;
const facultyColumnIndex = 2;
const mailAddressColumnIndex = 3;
const numColumns = 4;
const data = sheet.getRange(2, 1, sheet.getLastRow() - 1, numColumns).getValues();

var contacts = data.map(function(d){
return new Contact(
d[nameColumnIndex],
d[universityColumnIndex],
d[facultyColumnIndex],
d[mailAddressColumnIndex]
)})
return contacts;
}

/**
* Contactクラスの定義
*/

function Contact(name, university, faculty, mailAddress) {
this.name = name;
this.university = university;
this.faculty = faculty;
this.mailAddress = mailAddress;
}

今回は1行目がヘッダなので、あえて2行目からデータを抜き取っていますが、全セルのデータを抜き取るのであればgetDataRange()メソッドで範囲を指定すると良さそうです。

参考サイト→GASでSpreadsheetを操作する自分的ベストプラクティス

個々のオブジェクトとメソッドについては公式ドキュメントをご覧ください。


メインの処理(本文作成・メール送信)

ここまでで作成した関数を呼び出して、メールのテンプレートと連絡先を取得しています。

そのあと、連絡先1件ずつにつき、テンプレートからメール本文の作成、メールの送信を行っています。

function myFunction() {

const templateBody = getTemplateBody();
const contacts = getContacts();

contacts.forEach(function(contact){
const body = templateBody.replace('${name}', contact.name).replace('${university}', contact.university).replace('${faculty}', contact.faculty);
GmailApp.sendEmail(contact.mailAddress, "subject", body, {
name: "DaisukeKURATA"
})
})
}

Gmailの操作方法については公式ドキュメントをご覧ください。


補足

様々な種類のメールを自動配信しようというユースケースの場合、件名も固定値ではなく動的にしなくてはならないと思います。テンプレートファイルの名前をメールの件名にすると、わかりやすい&プログラムで件名を簡単に指定できるのでいい感じになります。


感想

全然関係ないですが、送る相手にはBotだとばれないようにしましょう。当時は月次業務関係(毎月5日〆切の依頼など)のメールもBotで配信していたのですが、Botだとばれると、見てくれないし、依頼もやってくれなくなります。ふざけんな^^

それはさておき、別記事でGoogleCalendarを操作する話をしましたが、今回の記事のように複数のGoogleアプリケーションをまたいだ操作もすることができます。実行環境を整えずにプログラムを書くことができるので非ソフトウェアエンジニアの人にもおすすめです!大学生の時は私プログラミングの勉強とかしていなかったので!


参考サイト

公式ドキュメント

Qiita イマドキのJavaScriptの書き方2018

GoogleAppsScriptでどこまで書けるのかを試しました。

「let」と「class」が使えないみたい・・・?

Qiita GASでSpreadsheetを操作する自分的ベストプラクティス

パフォーマンスの出る書き方という観点で記事がかいてあるので、大量のデータを扱う方は見るとよいかもしれません。

Qiita GASでのメール送信についてまとめてみる

日本語の記事なのでありがたや。