Gmailで大量の宛先(to)とccがあって、メールを新規作成するのがつらいときの処方箋

Gmailで大量に宛先とccを新規作成する時に、とてもつらかった。
こんな作業、もう2度とごめんだと思った。
そんな方に是非読んでもらいたい。

# 前提
最近は、[G Suite](https://gsuite.google.co.jp/intl/ja/)で社内のメールはGmailを使っているよって企業は増えていると思う。

社内では、コミュニケーション管理に（みんな大好き）SlackとかChatworkとか使ってプロジェクトを円滑に進めるように工夫を凝らしているところだろう。

一方、社外とのコミュニケーション管理でSlackやChatworkを導入したものの、結局社外のステークホルダーがメールしか見てくれないなんてシチュエーションがあるはず。
そう、メールなら見てくれるのだ！

# 課題
Gmailでメールを新規作成する際に、宛先が大量にあって、かつ抜け漏れがあるかもしれないし、なんだかんだで面倒くさいから、この無意味な作業をなんとかして効率化したい。
でも、Google先生は、ベストプラクティスを返してくれない。

ないものは作るに限る。

# 解決策
GoogleスプレッドシートとGoogleAppsScript(GAS)を用いて、この問題に対処することにした。
詳細は以下。

- 大量の宛先はGoogleスプレッドシートで管理する
- ついてに、件名と本文も同じように管理する
- メールの新規作成は https://mail.google.com/mail/?view=cm&fs=1 で作れる
- 上記URLにパラメータをつけることで、新規メールが作成できる
    - TO: &to=xxx@hoge.com,yyy@hoge.com,...
    - CC: &cc=xxx@hoge.com,yyy@hoge.com,...
    - BCC: &bcc=xxx@hoge.com,yyy@hoge.com,...
    - 件名: &su=
    - 本文: &body=

# 目指すべき形
最終形態は以下な感じ。これを目指す。

![spreadsheet_00.png](https://qiita-image-store.s3.amazonaws.com/0/70138/a8e586e9-c44c-771e-f19b-806ea6615e04.png)

![spreadsheet_01.png](https://qiita-image-store.s3.amazonaws.com/0/70138/96a85482-8528-de33-247b-263d6eb23d3b.png)

自前で作ったメニューを押下すると、シートに記入されている「件名」「本文」「メールアドレスのリスト」から、新規メールが作成できる。これだけ。
自画自賛するが、ほんと最高。

![spreadsheet_02.png](https://qiita-image-store.s3.amazonaws.com/0/70138/92e215e9-a860-4a47-6f93-54c918bf1850.png)

で、新規作成する内容を確認できる。
チェケラッチョ。

# GoogleAppsScript(GAS)のコード
```javascript
// スプレッドシートを開いた時に、メニューを追加する
function onOpen(){
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('新規メール作成');
  menu.addItem('新規メールを作成する', 'generateEmail');
  menu.addToUi();
}

function generateEmail() {
  // 変数を定義
  var emailCreatUrl = 'https://mail.google.com/mail/?view=cm&fs=1';
  var to = 'to';
  var cc = 'cc';
  var bcc = 'bcc';
  var toParam = '&to=';
  var ccParam = '&cc=';
  var bccParam = '&bcc=';
  var subjectParam = '&su=';
  var bodyParam = '&body=';
  var row = 7; // Start行
  var columnEmail = 3; // Start列 Email
  var columnType = 4; // Start列 タイプ
  var rowSubject = 3; // Start行 Subject
  var columnSubject = 2; // Start列 Subject
  var rowBody = 4; // Start行 Body
  var columnBody = 2; // Start列 Body
  var valueTO = '';
  var valueTOencoded = '';
  var valueCC = '';
  var valueCCencoded = '';
  var valueBCC = '';
  var valueBCCencoded = '';
  var valueSubject = '';
  var valueSubjectEncoded = '';
  var valueBody = '';
  var valueBodyEncoded = '';

  //セルの値を取得していく
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); //1. 現在のスプレッドシートを取得
  var sheet = spreadsheet.getActiveSheet(); //2. 現在のシートを取得
  // 設定する
  var rangeEmail = sheet.getRange(row,columnEmail); // StartのEmailを取得する
  var rangeType = sheet.getRange(row,columnType); // Startの区分を取得する
  var valueEmail = rangeEmail.getValue();
  var valueType = rangeType.getValue();

  // 宛先を設定する
  while(valueEmail) {
    // Emailの値をエンコードする
    var valueEmailEncoded = encodeURIComponent(valueEmail);
    // toかccかbccを判別する
    if(valueType == to){
      if(valueTO == ''){
        var valueTOencoded = toParam + valueEmailEncoded;
        var valueTO = valueEmail;
      }else{
        valueTOencoded += ',' + valueEmailEncoded;
        valueTO += ',' + valueEmail;
      }
    }else if(valueType == cc){
      if(valueCC == ''){
        var valueCCencoded = ccParam + valueEmailEncoded;
        var valueCC = valueEmail;
      }else{
        valueCCencoded += ',' + valueEmailEncoded;
        valueCC += ',' + valueEmail;
      }
    }else if(valueType == bcc){
      if(valueBCC == ''){
        var valueBCCencoded = bccParam + valueEmailEncoded;
        var valueBCC = valueEmail;
      }else{
        valueBCCencoded += ',' + valueEmailEncoded;
        valueBCC += ',' + valueEmail;
      }
    }
    var row = row + 1;

    // 再度設定する
    var rangeEmail = sheet.getRange(row,columnEmail); // StartのEmailを取得する
    var rangeType = sheet.getRange(row,columnType); // Startの区分を取得する
    var valueEmail = rangeEmail.getValue();
    var valueType = rangeType.getValue();
  }

  // 件名を設定する
  var rangeSubject = sheet.getRange(rowSubject,columnSubject); // Subjedtを取得する
  var valueSubject = rangeSubject.getValue();
  var valueSubjectEncoded = encodeURIComponent(valueSubject);

  // 本文を設置する
  var rangeBody = sheet.getRange(rowBody,columnBody); // Subjedtを取得する
  var valueBody = rangeBody.getValue();
  var valueBodyEncoded = encodeURIComponent(valueBody);

  emailCreatUrl += valueTOencoded + valueCCencoded + valueBCCencoded; // htmlを作成する
  if(valueSubject != ''){
    emailCreatUrl += subjectParam + valueSubjectEncoded;
  }
  if(valueBody != ''){
    emailCreatUrl += bodyParam + valueBodyEncoded;
  }
  var hlink = '=HYPERLINK("' + emailCreatUrl + '","メールを作成する")'; // HYPERLINKを作成する
  sheet.getRange(1,1).setValue(hlink); // セルを書き換える

  // ポップアップを表示する
  var messenger = Browser.msgBox('新規作成メール内容を確認する', '宛先(to)：' + valueTO + '\\n\\nCC：' + valueCC + '\\n\\n件名：' + valueSubject + '\\n\\n本文：' + valueBody + '\\n\\n上記の内容で新規メールの準備が整いました。', Browser.Buttons.OK_CANCEL);

}
```
## コードの説明
私はプログラマではない。
故に、アラのあるコードかもしれないが、その点はご容赦いただきたい。

```javascript
  var row = 7; // Start行
  var columnEmail = 3; // Start列 Email
  var columnType = 4; // Start列 タイプ
  var rowSubject = 3; // Start行 Subject
  var columnSubject = 2; // Start列 Subject
  var rowBody = 4; // Start行 Body
  var columnBody = 2; // Start列 Body
```
上記で、スプレッドシートの上の「メールのリストがどこから始まるのか？」とか「件名」「本文」の位置を指定している。
なので、スプレッドシートに手を加えたら、ここは必ず修正する。

whileの中なんかは、もうちょっとうまくかけると思ったが、まぁうごいているからいっか的なノリでそのままにしている。

# 最後に
これで、Gmalでの大量に宛先がある場合の新規メール作成に抵抗感がなくなった。
めでたしめでたし。