こんにちは。
キャスレーコンサルティングのSI(システム・インテグレーション)部のKanemakiと申します。

皆さん、GoogleAppsScriptは活用されていますか?

これまでも技術ブログでは
Google Apps Script入門
Google Apps Scriptで、心温まる年賀状を作ろう!
と過去に取り扱っていますが、今回はGoogleAppsScript(以下GAS)とラベルを活用したメール整理術をご紹介します。

紹介する内容
・ラベルによる自動振り分け
・GASによるリマインドメールの自動化

背景

弊社の組織体系は私が所属しているようなSI部のような部署がいくつかあり、その中にグループが存在します。
グループ全体では大体18名前後になります。

キャスレーでは社員は週報をGmailに送ります。それに対して読んだ人はレスを返したり、「いいね」が出来る「いいねシステム」を活用して、普段社外で働いているメンバーと社内のメンバーとのコミュニケーションの場として活用されています。

反面、メールが多くなるので、何も設定しないとグループメンバーのメールが探しにくくなってしまいます。
ここで活躍するのがメールのラベルとフィルタリング機能になります。これについて一つ目としてご説明いたします。
メールを探し易くするラベルとフィルタリングが出来ると次はこんな事をしたいという欲求が生まれます。

・まだ週報を出していない人へのリマインドメールを自動化したいな。

ルーチンワークはなるべく自動化したい。自動化することでチェック漏れや時間の節約して他の業務に専念したい。
その欲求に答えるのがGASになります。これについて二つ目としてご説明いたします。

ラベルとフィルタリング

Gmailのフィルタリングやラベルの設定にはまずGmail画面上の右上にある歯車ボタンを押して設定を選択します。

歯車

まずはラベルから作ります。
設定画面が表示されたらラベルタグを押下します。

スクリーンショット 2016-11-27 19.18.04_censored

[新しいラベルの作成]ボタンを押下します。
時計

すると、新しいラベルというポップアップが表示されますので「週報」と入力していきます。
そのままOKボタンを押下します。
すると、ベルの中に「週報」が作成されます。

フィルタ3
※「次のラベルの下位にネスト:」の項目は今回は特に設定しません。

ラベルのネスト

「週報」ラベルが作成されましたら、今度はその中にグループを作成します。
先ほどと同じように[新しいラベルの作成]ボタンを押下します。

時計

すると新しいラベルというポップアップが表示されますので「グループ」と入力していきます。
「次のラベルの下位にネスト:」で先ほど作成した週報を選択します。
※チェックボックスは選択することで自動的にチェックされます。
あとはOKボタンを押下します。

ネストグループ

これで以下のような構成になりました
週報
|-グループ

ラベルのネストは、フォルダ機能をイメージしていただくとわかりやすいと思います。

[コーヒーブレイク]小技ご紹介

実はこのラベル、色を付けて強調することが出来ます。
設定は簡単! Gmailの画面にてラベルを表示したら、その表示の右部分に▼が表示されているかと思います。

こちらで[ラベルの色]を設定するだけ!簡単ですね。

フィルタリング

Gmailのフィルタリング機能は、ラベルと同じくGmail画面上の右上にある歯車ボタンを押して設定を選択します。

歯車

ここで、[フィルタとブロック中のアドレス]タグを押下します。

フィルタタグ
[新しいフィルタを作成]ボタンを押下します。

フィルタ空

ここで対象を抽出する条件を記述します。
まずは、週報に対して全て週報ラベルを設定します。
対象は、「宛先は週報提出用メーリングリスト」の物を選択します。
To:の項目にメーリングリストアドレスを入力し、続行ボタンを押下します。

次にフィルタ動作を設定します。
・受信トレイをスキップする(アーカイブする)をチェックする
・ラベルをつける:週報
以上で設定は終わりです。

今まで受信したメールについてもフィルタする場合は、[一致するスレッドにもフィルタを適用する。]にチェックします。
以上の設定で、週報メールが全て週報ラベルに紐付きます。

グループラベルの作成

今度はグループラベルに設定するフィルタになります。
先ほどと同じように、新規フィルタの作成を始めます。

今回は週報メールの中で、メンバが送り主であるメールが対象になります。
ここでは、先ほどとは異なる方法で設定しましょう。
対象としてTo:に指定するのではなく[含む]に以下のように入力します。
label:(週報) from:(izumi.simomura@casley.co.jp OR kei.nagai@casley.co.jp OR yu.tosaki@casley.co.jp) after:2016/01/01

こうすることで、先ほど設定したラベル[週報]であり、かつ送り主にはメンバーとなった2016年の1月1日から受信したメールを全てフィルタする設定条件になります。
※このメールアドレスは実在のものとは異なります。
スクリーンショット 2016-11-27 19.20.41_censored

スクリーンショット 2016-11-27 19.21.09_censored

これで週報の中のメンバーからのメールに、グループラベルが付けられる事になります。

GASとは(復習)

次に、本題のGASについてですが、Gmail、Drive、Spreadsheet、Document、Calendar、Mapsなど、
様々なGoogleAppsのアプリケーションに独自の機能を追加するためのスクリプト言語です。

言語仕様はJavaScriptをベースにしており、JavaScript + GoogleAPIというイメージです。
各APIについては、GAS公式に網羅されています。 ※全て英語です

GASを使ったリマインドメール作成

処理の流れとして以下のような物を考えています。
・グループラベルがついたメールで一週間以内に送られていないメンバーに対してリマインドメールを送る

チェック対象のメンバーのアドレス一覧について直接記述しても良いですが、メンバー変更の度にソースをメンテするのはよろしくありません。
そこでGASのスプレッドシートを利用しましょう。

まずスプレッドシートに、このようなグループアドレスを管理する物を作成します。

スクリプトエディタ
次にGASを書いていきましょう。[ツール]から[スクリプトエディタ]を開きます。

スクリーンショット 2016-11-27 19.33.31_censored
エディタにGASを書いていきます。

まずは、先ほどのメールアドレスを取得する方法からです。
シート内の値を取得するには、getRangeとgetValueを使用します。

//スプレッドシートを取得し
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//スプレッドシート内のシートを取得します。 ex)シート名「アドレス設定」
var sheet = spreadsheet.getSheetByName("アドレス設定");
//シート内の値を取得するにはgetRange(x,y).getValue()を使います
var value = sheet.getRange(2,1).getValue();

Range(2,1)から縦方向に数セル取得する場合はgetValues()を使用します。

var values = Sheet.getRange(2,1,5).getValues();

メンバーのアドレスを取得したら今度はGmailの操作方法です。
Gmail内を検索するには以下のコードを利用します。

GmailApp.search(クエリー);

例えば
・グループラベルのついた
・1週間前以降に送られた
・特定のメンバーが送った
以上の条件でGmail内を検索するにはクエリーに対して、以下のような条件を指定します。
これは、Gmailの検索でも同じように使える文字列になります。

  var strTerms = 'label:週報-グループ after:' + startDate + ' from:' + targetAddress;
  var myThreads = GmailApp.search(strTerms);
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

しかし、スレッドで取得している為、週報では古いメールも含めて取得されてしまいます。
そこで今度は、スレッド内のメール一つずつを取得して、日付により最近提出されたものかを判断します。
※ここではわかりやすさを優先するために1スレッドに1名しか投稿されていない状態を仮定しております。

  /* 対象条件に一致するメールがあればtrue,無ければfalse */
  for(var i = 0;i < myMsgs.length;i++){ for(var j = myMsgs[i].length -1; j >= 0 ; j--){
      Logger.log('mail:' + myMsgs[i].length)
      if(myMsgs[i][j].getDate() < searchDate){
        break;
      }else{
        return true;
      }
    }
  }
  return false;

これでメンバーの中で、週報が提出されていない人が絞り込めます。

次にリマインドメールを送る方法です。
メールを送るには、以下のような記述になります。

GmailApp.sendEmail(recipient, subject, body)

以上で必要な部品は整いました。
最後に実際に作ったコードを、参考までに以下に記載します。

function sendRemind() {
  var subject ="メール件名"
  var body ="本文"

  var groupMenberAddresses ="";

  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName("アドレス設定");
  var values = sheet.getRange(2,1,3).getValues();

  groupMenberAddresses = values

  var unSendMenberAddress = _getWeeklyReportUnSendmenbers(groupMenberAddresses);
  GmailApp.sendEmail(unSendMenberAddress.join(','),subject,body)

}

function _getWeeklyReportUnSendmenbers(targetAddresses){
  var unSendMenbers =[];
  var sendFlg = false;

  var today = new Date();
  var t4b = new Date(today.getTime()-1000*60*60*24*7); //本日の7日前
  for(var i=0; i < targetAddresses.length; i++){
    sendFlg = _doCheckSendEmail(targetAddresses[i],t4b)
    if(!sendFlg){
      unSendMenbers.push(targetAddresses[i]);
    }
  }
  return unSendMenbers;
}

function _doCheckSendEmail(targetAddress,searchDate){
  var startDate = Utilities.formatDate(searchDate, "JST", "yyyy/M/dd");
  /* Gmailから特定条件のスレッドを検索しメールを取り出す */
  var strTerms = 'label:週報-グループ after:' + startDate + ' from:' + targetAddress;
  var myThreads = GmailApp.search(strTerms);
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  /* 対象条件に一致するメールがあればtrue,無ければfalse */
  for(var i = 0;i < myMsgs.length;i++){ for(var j = myMsgs[i].length -1; j >= 0 ; j--){
      Logger.log('mail:' + myMsgs[i].length)
      if(myMsgs[i][j].getDate() < searchDate){
        break;
      }else{
        return true;
      }
    }
  }
  return false;
}

毎週特定日に自動実行する

さて最後に、先ほどの週報未提出リマインドメールを自動実行する為の設定をしていきましょう。
スクリプトエディタの画面にある時計のアイコンをクリックします。

フィルタ2

トリガーというものを利用します。トリガーをクリックしましょう
トリガー

実行するメソッドと実行タイミングを設定しましょう。
トリガー

これで毎週自動実行され、対象者がいればメールを送ることができます。

以上です。簡単ですね。

まとめ

今回は、日頃のメール管理をちょっと工夫するだけで楽になる方法をご紹介いたしました。
みなさんの環境に合わせて、ぜひGASを使いこなし管理者としての管理業務の効率化を目指してはいかがでしょうか?
例えば《提出されたメンバーメールの内容を1つのメールにまとめて自分にメールを送る》事も出来ます。

ご一読頂き有難うございました。
Kanemaki