見出し画像

GAS超実践編① - 複数のメールアドレスに一斉送信

はじめに

「営業メールを1通1通手動で送信してる」「送信先ごとにメアドと会社名を変えて送信してる」

こんな面倒な処理に時間を取られてませんか?
職場の営業が新規営業でまさにこれをしてました。1日4時間くらい...w

昼飯を食べながらその話を聞いて、午後1時間くらいで一括送信のGASを作ってあげたらめちゃくちゃ感謝され、「作業時間が4時間 → 5分」に。部署の必須ツールとなっていました。笑

このような、一括送信もGASで簡単にできちゃいます。
※ ただし、GASからメールを送信する際には1アカウントにつき1日100件という制限があるので注意して下さい。

スプレッドシートに記載された件名と本文を送信してみる

以前、GASからGmailを送信する方法は以下の記事で解説しました。

今回は、スプレッドシートに書かれた件名・本文を取得して、メールを送ってみましょう。

シートを用意

スクリーンショット 2020-07-14 22.56.44

今回は、A列に件名、B列に本文を用意してみました。
※ このシート名は「テンプレート」と名前を付けておいてください。

まずはこの件名と本文を取得しましょう。

function sendAllMail() {
 // spreadSheetオブジェクトを取得
 let spreadSheet = SpreadsheetApp.getActive()
 
 // 件名と本文が書かれたsheetオブジェクトを取得
 let templateSheet = spreadSheet.getSheetByName("テンプレート")
 
 // 件名はA2セルに入ってるのでその値を取得
 let title = templateSheet.getRange("A2").getValue()
 
 // 本文はB2セルに入ってるのでその値を取得
 let body = templateSheet.getRange("B2").getValue()
 
 console.log(title, body)
}

ここまではもうお手のものですね。まだsheetオブジェクトとか良くわからない人はこちらの基礎編を復習してみてください。

また、最後にconsole.logを使っていますが、これがかなり便利です。
この状態で「表示」→「ログ」をクリックしてみてください。

画像3

まだ何も表示されてないと思います(遅いんです)ので、「Apps Scriptダッシュボード」という部分をクリックしてみてください。

画像4
かなりリアルタイムでログが出てきます。
そして、ちゃんと件名と本文が取得できたのが分かります。

メール送信_1
じゃあメールを送ってみましょうか。
GASからメールを送るのは非常に簡単です。

メール送信引数
GmailAppオブジェクトのsendEmailメソッドを使って、第一引数に送信先のメアド、第二引数に件名、第三引数に本文を入れればOKでした。

function sendAllMail() {
 // spreadSheetオブジェクトを取得
 let spreadSheet = SpreadsheetApp.getActive()
 
 // 件名と本文が書かれたsheetオブジェクトを取得
 let templateSheet = spreadSheet.getSheetByName("テンプレート")
 
 // 件名はA2セルに入ってるのでその値を取得
 let title = templateSheet.getRange("A2").getValue()
 
 // 本文はB2セルに入ってるのでその値を取得
 let body = templateSheet.getRange("B2").getValue()
 
 // スプレッドシートの件名・本文でメールを送信する
 GmailApp.sendEmail(【あなたのメールアドレス】, title, body)
}

コードはこんな感じです。【あなたのメールアドレス】の部分だけ、自分のメアドに置き換えてください。

これで実行してみると、スプレッドシートに書いた件名・本文でメールが送れるようになりました。

メール送信2

スプレッドシートに記載されたメールアドレスに送信してみる

件名と本文はスプレッドシートに書かれたものから送信できました。
次はいよいよ実践に近づいていきます。

スプレッドシートに送信対象のメールアドレスの一覧を記載して、そこに対してメールを送信してみましょう。

メアドリスト_2


さて、今回はA列に送信対象のメールアドレス一覧を書いたシート(「メールアドレス」という名前のシート)を作ってみました。

「こんなにメアドがないよ!」という人もご安心ください。
【hogehoge@gmail.com】という人は、【hogehoge+1@gmail.com】【hogehoge+2@gmail.com】のように、アカウント名の後に「+」で文字をつなげると、送信先は同じでも、別メアドとして識別できるので、自分のアカウント名に「+」で連番を振ってみましょう。

参考 → https://www.howtonote.jp/gmail/sent/index18.html

メアドリスト03

コードを書いていきましょう!

function sendAllMail() {
 // spreadSheetオブジェクトを取得
 let spreadSheet = SpreadsheetApp.getActive()
 
 // 件名と本文が書かれたsheetオブジェクトを取得
 let templateSheet = spreadSheet.getSheetByName("テンプレート")
 
 // 件名はA2セルに入ってるのでその値を取得
 let title = templateSheet.getRange("A2").getValue()
 
 // 本文はB2セルに入ってるのでその値を取得
 let body = templateSheet.getRange("B2").getValue()
 
 // 送信対象のメールアドレス一覧が記載されてるシートを取得
 let targetSheet = spreadSheet.getSheetByName("メールアドレス")
 
 // メールアドレスの一覧を取得する
 let targets = targetSheet.getRange(2, 1, targetSheet.getLastRow() - 1, 1).getValues()
 
 // 取得したメールアドレス一覧を表示してみる
 for (target of targets) {
   console.log(target)
 }
 

 /*  
 // スプレッドシートの件名・本文でメールを送信する
 GmailApp.sendEmail("【あなたのメールアドレス】", title, body)
 */
}

一旦メールを送信する処理はコメントアウトしました。
メールアドレスというシートから、A列の値を全て拾ってきています。ログを見てみましょう。

メアド_04

良い感じですね!

企業名を置換してみる

ただ、このままだと全てのメールの本文が「株式会社スキプラ 様」になってしまいますね。
そこで、スプレッドシートに会社名も書いて、本文の会社名の部分を置換して企業毎に本文を書き換えられるようにしてみましょう。

先程の「メールアドレス」のシートのB列に企業名を書いてみましょう。

メアドリスト

まずは、先程のコードを少し修正して、メールアドレスと企業名の両方を取得できるようにします。

  // メールアドレスと企業名の一覧を取得する
 let targets = targetSheet.getRange(2, 1, targetSheet.getLastRow() - 1, 2).getValues()
 
 // 取得したメールアドレスと企業名の一覧を表示してみる
 for (target of targets) {
   console.log(target[0], target[1])
 }

変えたのは、getRangeの最後の列数を「1 → 2」にしたのと、こうすることで二次元配列にはスプレッドシートに記載されてる通り、1列目(target[0])にメアドが入り、2列目(target[1])に企業名が入ります。ログを見てみましょう。

メアドリスト05
よし、メアドだけじゃなくて企業名も取得できてますね!

GAS入門7- LINEに通知するのコピー

replaceメソッドとは、文字列の中の特定の文字を置換する処理です。

スクリーンショット 2020-07-14 23.34.19

このように使います。
実際に書いてみましょう!

まず、置換したい文字として、先程の「テンプレート」シートのB列の本文の会社名のところを「%企業名%」としてみます。

スクリーンショット 2020-07-14 23.35.13
「%」で囲っているのは以下のような理由です。

1. %で囲うことで「これは置換される文字列だよ」と明示してる。2. 「企業名」を置換対象にすると、思いがけず本文中に「企業名」という単語が出てきた時、そこも予期せず置換されるのを防ぐ
  // 本文の「%企業名%」を企業名に置き換えてみる
 for (target of targets) {
   body = body.replace(/%企業名%/, target[1])
   console.log(body)
 }

このように、先程「テンプレート」シートから取得した本文(body)の「%企業名%」をtarget[1] (これは「メールアドレス」シートの企業名)に置換してます。

スクリーンショット 2020-07-14 23.38.40

おや、全ての企業名が「株式会社スキプラA」になってますね(便宜的に本文を2行までにしました)

これは、「メールアドレス」シートで取得したメールアドレス分だけループで回してますが、最初の1回目の置換で、bodyという変数の中身は以下のように変わってます。

▼ 置換前

%企業名% 様
はじめまして。スキプラと申します。

▼ 1回目のループでの置換後

株式会社スキプラA 様
はじめまして。スキプラと申します。

こうなると、2回目も「%企業名%」を置換しようとしますが、bodyの中身はすでに入れ替わってるので、置換対象の文字列がなくて全部「株式会社スキプラA」になってしまってるのです。

では、bodyの取得をループの中に持ってきましょう。

  // 本文の「%企業名%」を企業名に置き換えてみる
 for (target of targets) {
   // 本文はB2セルに入ってるのでその値を取得
   let body = templateSheet.getRange("B2").getValue()

   body = body.replace(/%企業名%/, target[1])
   console.log(body)
 }

※ 効率良くないですが、一旦割愛しますね。

スクリーンショット 2020-07-14 23.44.12


ちゃんと置換されました!では一斉メール送信を行ってみましょう。

  // 本文の「%企業名%」を企業名に置き換えてメールを送信
 for (target of targets) {
   // 本文はB2セルに入ってるのでその値を取得
   let body = templateSheet.getRange("B2").getValue()
   body = body.replace(/%企業名%/, target[1])

   // スプレッドシートのメアド、件名・本文でメールを送信する
   GmailApp.sendEmail(target[0], title, body)
 }

ループの中身をこのように変更して実行してみましょう!

スクリーンショット 2020-07-14 23.46.22
ちゃんと企業名は置換されてるみたいですね。あとは送信先のメアドも変わってるかチェックです。

gmail01の送信株式会社スキプラAの送信先のメールアドレスは「xxxx+01@gmail.com」になっていますね。

gmail10の送信

そして、株式会社スキプラJの送信先は「xxxx+10@gmail.com」にちゃんと変わっているのが分かります。

一斉送信するボタンを作ってみる

まだ、毎回スクリプトエディタを開いて実行してると面倒ですよね。
どこで、スプレッドシートにボタンを作って、ボタンを押したらメールが送信されるようにしてみましょう

これは思ってる以上に簡単にできます。

スクリーンショット 2020-07-15 00.10.34

まず、スプレッドシートのボタンを設置したいシートを開き「挿入」→「図形描画」をクリックしてください。

スクリーンショット 2020-07-15 00.10.48

するとこんなパワポみたいな画面ができてますので、画像のように、「図形のマーク」→「図形」→「□のマーク」をクリックします。

スクリーンショット 2020-07-15 00.11.29
一旦色とかはデフォルトのまま、文字だけ入れてみます。作ったら、右上の緑色の「保存して終了」を押します。

スクリーンショット 2020-07-15 00.11.44

するとスプレッドシートにこのようなボタンができますので、図形を右クリックしてください。画像のように●が3つのメニューが表示されてるので、これをクリックします。

スクリーンショット 2020-07-15 00.11.50

●が3つの下にメニューが表示されますので、「スクリプトを割り当て」をクリックしてください。

スクリーンショット 2020-07-15 00.12.14
どのスクリプトを割り当てますか?と聞かれますので、ここで先程までスクリプトエディタで作っていた関数名(僕はsendAllMailと命名しました)を入力して「OK」を押します。

これでボタンを押してみますね!!

スクリプト実行1

先程のボタンを意気揚々と押してみます。
しばらくすると画面上部に「スクリプトを実行しています」と表示されます。

スクリプト実行02

さらにもうしばらくすると、「スクリプトが終了しました」という表示に切り替わり、処理の終了を教えてくれます。
実際にメールを見てみましょう!

スクリーンショット 2020-07-15 00.33.26


ちゃんと送れてますね!

誤送信を防ぐ処理を入れてみる

誤ってボタンを押してしまったら、同じメールが2通・・3通・・5通と送られてしまい「何だこの会社は!迷惑企業か!」というクレーム必須です。

それを防ぐために、ボタンを押した時に確認のアラートを出して、「OK」を押した時だけメールが送信されるようにしてみましょう。

 // 間違えて押した時にキャンセルできるようにアラートを出す
 let confirm = Browser.msgBox("メール一斉送信","本当に送信してもよろしいですか?", Browser.Buttons.OK_CANCEL)

 // キャンセルが押されたら、操作を中止する
 if (confirm == "cancel") {
   Browser.msgBox("一斉送信をキャンセルしました")


   // ここで処理を終わらせる    
   return false;
 }  

先程のsendAllMail関数の先頭にこの処理を入れます。
するとボタンを押した時にこんなアラートが出るようになります。

スクリーンショット 2020-07-15 00.38.48

BrowserオブジェクトのmsgBoxで、関数が呼び出された時 = ボタンが押された時に、アラートを出すことができます。

このconfirmには、「ok」か「cancel」が入ってきます (押したボタンによって変わります。

ここで「キャンセル」を押すと、、、

スクリーンショット 2020-07-15 00.39.13

このように表示されて、一斉送信をキャンセルすることができます。

これで誤送信も防げて安心ですね!

コードの最終形

function sendAllMail() {
 
 // 間違えて押した時にキャンセルできるようにアラートを出す
 let confirm = Browser.msgBox("メール一斉送信","本当に送信してもよろしいですか?", Browser.Buttons.OK_CANCEL)

 // キャンセルが押されたら、操作を中止する
 if (confirm == "cancel") {
   Browser.msgBox("一斉送信をキャンセルしました")

   // ここで処理を終わらせる    
   return false;
 }  
   
 // spreadSheetオブジェクトを取得
 let spreadSheet = SpreadsheetApp.getActive()
 
 // 件名と本文が書かれたsheetオブジェクトを取得
 let templateSheet = spreadSheet.getSheetByName("テンプレート")
 
 // 件名はA2セルに入ってるのでその値を取得
 let title = templateSheet.getRange("A2").getValue()
 
 // 送信対象のメールアドレス一覧が記載されてるシートを取得
 let targetSheet = spreadSheet.getSheetByName("メールアドレス")
 
 // メールアドレスと企業名の一覧を取得する
 let targets = targetSheet.getRange(2, 1, targetSheet.getLastRow() - 1, 2).getValues()
 
 // 本文の「%企業名%」を企業名に置き換えてメールを送信
 for (target of targets) {
   // 本文はB2セルに入ってるのでその値を取得
   let body = templateSheet.getRange("B2").getValue()
   body = body.replace(/%企業名%/, target[1])

   // スプレッドシートのメアド、件名・本文でメールを送信する
   GmailApp.sendEmail(target[0], title, body)
 }
}

もっと上を目指したい方へ

実際には、本文の中に「名前を置換したい」とか「添付ファイルを付けたい」とか色々やりたいことが出てくると思います。

また別の会で、「添付ファイルの付け方」は解説しますが、名前を置換する方法はreplaceで簡単にできますので、ぜひトライしてみてください!

さいごにお願い

スキ!シェアしてください!

いいなと思ったら応援しよう!

スキプラ@元エンジニア
実践編で利用するための基礎編はすべて無料公開してます。 基礎編のモチベーション向上のためにサポートして頂けるとめちゃくちゃ喜びます!! だいたい作業工数は1記事あたり4-5時間程度かけて【分かりやすい】【知識が身につく!】を意識して作っておりますので、今後も頑張っていきます!