宛先ごとに本文をカスタムしたメールをGoogle Apps Script( javascript )で一括送信する

## 背景
アカウント名やパスワードを一括配布する機会があったので、GAS(Google Apps Script)で実施しました。

## 処理の概要
下記のスプレッドシートの情報を基に一括メール送信します。
シート名は「スクリプト用データ」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347198/d0afcda3-b20f-2935-edcb-c92c9608b214.png)

完了フラグが`complete`、`fail`、`processing`以外のみ、メールの送信対象となります。
送信後は完了フラグ列を自動で更新します。

## 処理の流れ
① スプレッドシートからデータを取得する
② ①のデータを基にメール送信に必要なデータを作成する
③ ②で作成したデータを使いメール送信する
④ シートを更新する
以上です。

メール送信に失敗した場合のエラーハンドリングでは、送信者にメール通知します。

### ソースコード
▼メール送信

```javascript:main
function main() {
	//申請者向けメール本文;
	const EMAIL_BODY_PREFIX = "お疲れ様です。\n下記があなたのアカウントです。\n";
	const EMAIL_BODY_SUFFIX = "\n以上になります。よろしくお願いします。";
	//スプレッドシート操作クラス;
	const sheetDataManager = new SheetDataManager();
	//メール送信対象情報を一括取得;
	const sheetData = sheetDataManager.getSheetData();
	//メール送信対象分メールを送信する
	sheetData.forEach((item) => {
		try {
            //スプレッドシートの「送信完了」フラグ更新
            sheetDataManager.updateProcessingStateFlag(item.get("No."),"processing");
			MailApp.sendEmail({
				to: item.get("宛先"),
				cc: item.get("cc"),
				bcc: item.get("bcc"),
				subject: "アカウントの通知",
				body:item.get("宛先名") + EMAIL_BODY_PREFIX + item.get("アカウント") + EMAIL_BODY_SUFFIX,
			});
            //スプレッドシートの「送信完了」フラグ更新
			sheetDataManager.updateProcessingStateFlag(item.get("No."),"complate");
		} catch (e) {
            //スプレッドシートの「送信完了」フラグ更新
			sheetDataManager.updateProcessingStateFlag(item.get("No."),"fail");
			MailApp.sendEmail({
				to: item.get("送信者"),
				subject: "エラー発生報告",
				body: "No." + item.get("No.") + " でエラーが発生しました。",
			});
		}
	});
}
```
▼スプレッドシートデータ操作クラス

```javascript:SheetDataManager
class SheetDataManager {
	constructor() {
		//スプレッドシート取得
		this.spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
		this.sheet = this.spreadsheet.getSheetByName("スクリプト用データ");
	}

	//メール送信対象情報を一括取得
	getSheetData() {
		const sheetData = new Array();
		//入力のある最終行数
		const lastRow = this.sheet.getLastRow();
		//スプレッドシートの行数分繰り返す
		for (let i = 2; i <= lastRow; i++) {
			//スプレッドシートから完了フラグを取得
			const flag = this.sheet.getRange(i, 8).getValue();
			//メール送信が未完了の対象を配列に追加する
			if (flag != "complete" && flag != "fail" && flag != "processing") {
				//配列に追加する前にMapにまとめる
				const singleSheetData = new Map();
				//メール本文作成
				const userName = this.sheet.getRange(i, 5).getValue() + "さん";
				const account = this.sheet.getRange(i, 7).getValue();
				//Mapにまとめる
				singleSheetData.set("宛先名", userName);
				singleSheetData.set("アカウント", account);
				singleSheetData.set("No.", this.sheet.getRange(i, 1).getValue());
				singleSheetData.set("宛先", this.sheet.getRange(i, 2).getValue());
				singleSheetData.set("cc", this.sheet.getRange(i, 3).getValue());
				singleSheetData.set("bcc", this.sheet.getRange(i, 4).getValue());
				singleSheetData.set("送信者", this.sheet.getRange(i, 6).getValue());
				//Mapを配列に追加
				sheetData.push(singleSheetData);
			}
		}
		//メール送信が未完了の対象を追加した配列を返す
		return sheetData;
	}

    //スプレッドシートの「送信完了」フラグ更新
	updateProcessingStateFlag(num,flag) {
		this.sheet.getRange(num + 1, 8).setValue(flag);
	}
}
```

## 蛇足
実際はメール本文のカスタマイズがもう少しだけ複雑でしたが省きました。

javascriptの書き方でおかしなところがあれば教えていただきたいです。
短時間で作成したコードですが、問題なく動作しますので、何かの参考にしていただければと思います。