【Missionday運営Tips】GASでGmailの添付ファイルをGoogleDriveに保存して詳細をSpreadsheetにまとめる

#Hello Agents.
この記事ではNiantic社[^1]の位置ゲーIngressのイベント、Missiondayの運営に際して使用したちょっとした小技を紹介しています。
主にGoogleAppsScriptというGoogle製のサービスを自動化するプログラミング環境でのテクニックです。

これからMissondayを開催したいというエージェント[^2]の方々にとって少しでも助けになりますように。

##書いた人
Enlightenedのnowdonです。
Missionday堺(2017/3/19)、Missionday泉南(2017/4/29)にて主に申請関係担当としてチェックアウトメールの処理や、当日対面チェックアウトの処理のお仕事をしていました。
尚、~~本業~~ 副業はコード書きではないのでその筋の人が見ればクソみたいなコードかもしれませんがその辺はごめんなさい。
というか誰か俺にコードの書き方を教えてくれ、たのむ。

##参考資料
以下のサイトのスクリプトを参考に、Missionday向けにカスタマイズしたものです。
http://noriaki.hatenablog.com/entry/gmail-attachments-in-google-drive-based-on-google-apps-script
また、公式のリファレンスはこちらです。
https://developers.google.com/apps-script/

#Missiondayにおけるチェックアウトメールの処理
###チェックアウトメールの審査
多くの場合、Missiondayではチェックアウト時に運営スタッフが用意したGmailアドレスにIngressのStats画面のスクリーンショットを添付してもらい、担当スタッフがスクリーンショットを確認して審査することになります。
このメールが大体1000通くらいあって、スタッフが人海戦術でチェックしていくことになるのですが、複数名が同じアカウントにログインしてGmailにアクセスするということはできません。[^3]

###みんなだいすきスプレッドシート
そこで、エージェントの皆さんの間では大人気の[^4]Googleスプレッドシートに受信メールをリスト化し、GoogleDriveに添付ファイルを保存して複数人でチェック作業を進められるようにしてしまいましょう。
Gmailで受信したメールをリスト化して添付ファイルを一括で保存するには、Outlook等のサードパーティ製メールソフトのマクロ機能で実現可能ですが、GoogleAppsScriptを使えば同じことをGoogleのサーバー上のみで完結させることができます。

##チェックアウトメールを処理するGAS
###GoogleAppsScript(GAS)ってなに？
GoogleAppsScript(GAS)とは、GmailやGoogleDrive、GoogleカレンダーなどのGoogle製のサービスをプログラミングにより操作できるJavaScriptベースの開発環境です。
ちょうどMicrosoftOfficeなんかで使うVBAに近いものではありますが、ひとつの大きな違いとして、サーバーサイドのスクリプト言語であるということが挙げられます。
つまり、Googleのサーバー上で動作するので**PCを立ち上げていなくても特定の時間に実行したり、スプレッドシートが更新されたことをトリガーにしてスクリプトを実行する**ことが可能です。

###コード本体
こちらを自分のGoogleDriveにコピーして使ってください。
https://drive.google.com/open?id=1Rvfip4g6fh7SEMhwdHSY-ci5797pBuOy8Q-rN1UG9MkyBKPY2CpeAPAO

##使い方
###事前準備(スプレッドシート)
自分のGoogleDriveにメールのリストを作成するスプレッドシートを作成して、IDをコピーしておきます。
スプレッドシートのIDはURLを見ればわかります。
例えばスプレッドシートのURLが、
ttps://docs.google.com/spreadsheets/d/\<YOUR SPREADSHEET ID\>/edit#gid=0
となっていたら、[YOUR SPREADSHEET ID]の部分がIDです。
![2017-04-26_02h29_21.png](https://qiita-image-store.s3.amazonaws.com/0/56640/6475dec9-9524-ab30-2885-95ca1ee1cdfa.png)

###事前準備(GAS)
スクリプトのStartProgram関数(51行目～64行目)内で、SPREADSHEET_FILE_IDの値を設定します。
先程コピーしておいたスプレッドシートのIDです。

```javascript:StartProgram
function StartProgram() {  
  var DRIVE_FOLDER = "GmailAttachments";  
  var GMAIL_LABEL  = "Processed";
  // Write your spreadsheet ID
  var SPREADSHEET_FILE_ID = "<YOUR SPREADSHEET ID>";
  var SPREADSHEET_SHEET_NAME = "mail_list"

...

}
```

尚、上記の部分で添付ファイルを保存するフォルダや、リストを記録するシート名などの設定もできます。
設定等でスクリプトの内容を変更した場合、必ずスクリプトを保存してください。

###スクリプトの実行
[実行]メニューから[Authorize]を実行してください。
この作業は1回のみでOKです。
初回実行時には「承認が必要です」というダイアログボックスが表示されるので「許可を確認」ボタンを押し、承認してください。
![2017-04-26_01h13_53.png](https://qiita-image-store.s3.amazonaws.com/0/56640/0d7fa429-1371-1651-587c-1ccb5e6943ed.png)
![2017-04-26_01h14_10.png](https://qiita-image-store.s3.amazonaws.com/0/56640/23c47764-1b5a-6d6c-1b50-30968b11c4bf.png)

##実行結果
###トリガーの設定
スクリプトを実行すると時間主導型のトリガーが設定されます。
Linuxで言うcronみたいな働きをします。
タイミングは97行目～100行目で設定できます[^5]。

```javascript:トリガーの設定
  ScriptApp.newTrigger('saveGmailAttachments')
   .timeBased()
   .everyMinutes(5) // ここでタイミングを設定する
   .create(); 

```

これで定期的にスクリプトが実行されます。

設定されたトリガーはスクリプトの上部のメニューで確認できます。
![2017-04-26_00h23_14.png](https://qiita-image-store.s3.amazonaws.com/0/56640/452189e2-7998-94e9-9f51-4fe734b5b30d.png)
![2017-04-26_00h23_33.png](https://qiita-image-store.s3.amazonaws.com/0/56640/9ded2f10-b41b-4129-13f0-b9225dd06eae.png)

###実際に動くとこんな感じ
添付ファイル付きのメールが送られてくるとスプレッドシートにはこのようにメールの詳細が記録されます。
![2017-04-26_01h18_25.png](https://qiita-image-store.s3.amazonaws.com/0/56640/eb0636c8-ab93-4389-56a7-47d2ed768ff6.png)
F列以降には添付ファイルの保存先のリンクが挿入されます。
共同でチェックアウトメールに添付されたスクショをチェックするにはこのようにリンクを挿入してあげると作業効率が良いです。

保存先のフォルダにも添付ファイルが保存されています。
![2017-04-26_01h19_08.png](https://qiita-image-store.s3.amazonaws.com/0/56640/6c7e1405-881a-9d72-ba1a-4e5568273a9a.png)

###スクリプトの停止と再実行
スクリプトの自動実行を停止する際は、上記のトリガー設定のダイアログボックスから設定されているトリガーを削除してください。
再度実行する場合ですが、保存先等同じ設定で実行したい場合はトリガーの設定でsaveGmailAttachments関数のトリガーを設定するだけでOKです。
これは最初にAuthorize関数を実行した際にsetPropertiesメソッドでスクリプトのプロパティとして保存先等を設定しているためです。

```javascript:scriptPropertiesの設定
 PropertiesService.getScriptProperties().setProperty('HOGE', fuga);
```

このような記述でHOGEというプロパティにfugaという値が設定されます。

##注意事項
Gmailの仕様上ラベルはスレッドに対して付けられます
例えば2通メールを送ってきた場合にそのメールがスレッド化されてしまうことがあります。
その場合ラベルはどうなるのかというと、どうもこのスクリプトの挙動を見てるとスレッドに新しいメールが追加されるとラベルが付いてないと判定されるようなのですが、145行目でProcessedラベル付きを除外していると取得漏れが発生する可能性があります。

また、このスクリプトでは送信元も記録するようにしていますが、個人情報ですので取り扱いは十分気をつけてください。
スタッフ間で共有する場合はこの処理は除外するか、共有する際に削除することを推奨します。

#おわりに
エージェントのみなさまに於かれましては、スキャナの外ではGoogleDriveやスプレッドシート等、Google製のサービスを使う機会が多いかと思います。
GoogleAppsScriptはそれらのサービスを繋ぎ、自動化するためのツールです。
スキャナ外でのエージェント活動にて「こんなこと、自動化できそうだよなあ」みたいなことがあれば少しググってみてください。

『できそうなこと』はほとんどの場合『できること』。
あとは『調べる根気』と『身につける努力』です。

それではみなさま、良きエージェントライフを。


---
[^1]: ポケモンGOのとこ
[^2]: Ingressのプレイヤーはエージェントと呼ばれます
[^3]: いや、できるとは思うんだけど不審なログインとして最悪アカウントロックされるから注意な
[^4]: まあIngress自体がGoogleアカウント使ってんだから当然だよね
[^5]: 大体5分おきに設定するのがよいかなと思います