2018年11月29日木曜日

Google Apps Script を使って、特定条件に一致した Gmail の添付ファイルを Googleドライブへ保存する方法

2018年12月18日 スターによる判別を追加(末尾のAppendix参照)
2018年12月21日 応用A 差出人ごとにフォルダに分けて保存
2019年01月09日 応用B Gmail の未読迷惑メール一覧をメールで受信する

この手の情報はネットで検索するといろいろ見つかりますが、最初から順番にやり方を書いたサイトがなかなか見つからなかったので備忘録を込めて書き出しておくことにしました。ここで説明するコードはとてもシンプルです。実際にはこれを応用していろいろできるかなといったところです。

ロジックとしては次の通りです。
1. Gmailの検索機能を使って、「未読 AND 検索演算子」で該当メールを絞り込む
2. 絞り込んだメールに添付ファイルがあれば、それを抜き出して Googleドライブの指定したフォルダに保存(ファイル名は、「差出人_ファイル名」)
3. 絞り込んだメールの添付ファイルチェック&抜き出しが終了すれば、そのメールは既読にする

こうすることで、この Google Apps Script を何回実行しても1度のみの実行で済むことになります。このあたりは「既読」「未読」で判定するのか、「処理済み」ラベルがあるかないかなどで判別するかは好きなようにしたらよいと思います。

またファイル名が「差出人_ファイル名」となっているのは、誰から送られてきたメールなのかファイル名にいれないと、分からない場合があるということです。このあたりは、用途に応じて変更したらよいです。

Step 1. Googleドライブから Google Apps Script を使えるようにする


  1. ブラウザより Googleドライブ(https://drive.google.com)にアクセスします。
  2. 左上の「新規」> 「その他」>「アプリの追加」を選択
  3.  検索窓で「Google Apps Script」を入れて、Enterを押す
  4. Google Apps Script を「接続する」ボタンをクリック
これをすると、下図のように、Google Apps Script が追加されます。


うまくいけば、「新規」 > 「その他」に Google Apps Scriptが追加されています。


Step 2. 作業フォルダを作成し、Google Apps Script を新規作成する


新規 > その他 > Google Apps Script を開きます。

コードサンプルは次の通りです。
をコピーして、開いた Google Apps Script エディタの中身を消して、ペーストしてください。そして一旦保存してください。名前はなんでもよいです。
ここでは、「getAttechedFilefromGmailtoDrive」としています。

ここで変更が必要なのは3点です。
  1. var FOLDER_ID = '[Google Drive Folder ID]'; //保存するフォルダ
  2. var SEARCH_TERM = 'is:unread [Search Keywords for Gmail]';
  3. var myThreads = GmailApp.search(SEARCH_TERM, 0, 30); //条件にマッチしたスレッドを検索して取得 / 最大500 
一つずつ説明します。

var FOLDER_ID = '[Google Drive Folder ID]';

保存したいGoogleドライブにウェブからアクセスすると、そのURLは
  • https://drive.google.com/drive/folders/フォルダID
になります。
そのフォルダIDを指定します。
var FOLDER_ID = 'フォルダID'; 
のように設定します。

var SEARCH_TERM = 'is:unread [Search Keywords for Gmail]';

このサンプルコードでは一度に処理できる数は最大500です。
加えて、Google Apps Script の制限事項として、5分以内で処理がおわる必要があります。そのため、ある程度絞り込む必要があります。

is:unread は「未読」を意味して、未読 + 特定条件になります。
たとえば、特定の目的に沿って添付ファイルを送ってそれをまとめて1つのフォルダにいれたいとしましょう。
その場合には、件名を決め打ちにしてもいいですけれど Googleフォームなんかを使わない限り、誰か件名のタイプミスが生じる可能性があります。
そのため、エイリアスをつかうのがオススメです。
 ◯◯@gmail.com 
だとするなら
◯◯+hogehogeevent2018@gmail.com 
などの宛先におくってもらう(エイリアス機能で◯◯@gmail.com に届く)。
そして有効期限が、 2018年12月10日〜12月31日だとするなら


var SEARCH_TERM = 'is:unread to:◯◯+hogehogeevent2018@gmail.com before:2019/01/01 after:2018/12/10';

という条件設定になります。つまりは、下記の4つをすべて満たすメールということになります。
  1. 未読
  2. 宛先「◯◯+hogehogeevent2018@gmail.com」
  3. 2019年1月1日以前(つまり1日前の 2019年12月31日)
  4. 2018年12月10日以降

var myThreads = GmailApp.search(SEARCH_TERM, 0, 30); 


この場合、条件にマッチしたメールから最大30件抽出する設定です。最大は500までです。ここで注意点は、一日に Google Apps Scriptで抽出できる件数上限が低いことです。


の Email read/write (excluding send) によれば、
  • 無料版Gmail  20,000件/日
  • G Suite 50,000件/日
です。
一回30件なら、666回まで実行できますが、最大の500にすると わずか40回実行するだけで 20,000 回になります。もし5分おきに自動実行するトリガーをしかけていたなら、1時間に12回実行されるわけなので G Suite なら耐えられますが、無料版はオーバーしちゃいますので注意。

STEP3. 手動実行による動作検証



上図の「再生」マークをクリックしてください。
最初の1度目は、Google Apps Script が Gmail等にアクセスする許可を聞いてきます。「許可」してください。

これで意図したとおり Googleドライブにデータが入っていたら成功です。
また2度目に実行したときに、同じ添付ファイルが保存されていないことも確認してください。



上記は Word を抜き出した例です。

付録:時間による自動実行




  1. Google Apps Scriptエディタの編集メニューにある「現在のプロジェクトのトリガー」を選択します。
  2. 「+ トリガーを追加」ボタンをクリック
  3. 以下のように「時間主導型」にして、頻度を設定します。
上記だと1時間ごとに、getAttechedFilefromGmailtoDrive ファイルに保存した getMail関数が呼び出されます。

Appendix: 既読判別ではなく、スターによる判別をつかう


既読での判別は、メールを読まない場合はいいのですが、メールを担当者が読みながらシステムを稼働したい場合には使えません。その場合には既読の代わりにスターを使って判別する方法があります。ただし is:starred の場合には、スターがついた「スレッド」ごと判定されるため、is:unread のようにうまくいきません。そのことも含めて説明します。

サンプルコード

既読と異なるのは、Gmail検索でスター判別するのではなく、メッセージを処理する中でそこにスターがついているかどうかで判別しています。このコードは、【GAS】Gmailのメッセージにスターがついているか判定する方法とスターを付与する方法を参考にさせていただきました。

まとめ


Google Apps Script で一括処理はとても手軽で便利なのですが、制限があることに注意してください。それを超える場合には、たとえば電子メールソフトをつかうことで解決するかもしれません。

Thunderbird(IMAP設定)+ AttachmentExtractorアドオンで特定ラベルのメール内添付ファイルを一括保存(https://kitaney-google.blogspot.com/2014/09/googlegmail.html の「Appendix: 取り込んだメールから添付ファイルだけをファイルとして取り出したい!!」参照)

などの方法もあります。

2018年11月29日 @kimipooh

2018年11月17日土曜日

Pixel 3 で夜景モードを試してみた

現地時間18時に、ジャカルタのとある場所の室内から外の写真を撮っただけなので、そこまで参考になるかどうかはわかりません。ただ、試したことは備忘録として残しておかねば!ってモチベーションで書いてます。

まずは Google Play から Googleカメラのアップデートを確認




アップデートして、カメラのその他に「夜景モード」が追加されていたら準備万端です!

下記のように、かなり綺麗に写っているなぁと思いました。
特に暗いところになると、Googleカメラが、「夜景モードを試す」というメッセージを出してくれます。そこをタップしたら夜景モードになります。便利ですね!
またいろいろと試してみなければと思います!

夜景モード




通常モード(フラッシュなし)





iPhoneX のカメラ(通常モード、フラッシュなし)




iPhoneX の Night Camera アプリ




後に空港内から外の景色をとると


通常だと、かなり暗いですね。

下記のように夜景モードだとかなり明るくなっているのが分かります。これは結構つかそうですね!



2018年11月17日 @kimipooh

2018年11月12日月曜日

Google クラウドにデータってどのように保存されてるのだろう?

Google サービスを使っていると、そのデータが Google のどこかのデータセンターにあるサーバーに暗号化されて保存されているだろうというイメージまでは理解できますが、実際にどのような手法で保存されているかまでは分からないと思います。そのため、たとえばサーバーからデータが盗まれたり、見られたりすると漏洩するんじゃないかと不安に思う場合もあるかもしれません。

その疑問について、10月23日に開催された Google Cloud Summit '18 in 大阪 の展示ブースのや実際に説明を聞きました。そのことを紹介してみたいと思います。

たとえハードディスクを Google データセンターから盗み出しても意味がない


ファイルは、複数拠点・複数サーバーにランダムに分散保存されるので、1つのデータセンターのデータをまるごと盗んだとしても、目的にファイルを元の形にすることは不可能に近い。さらにデータセンターもGoogle社員だとしても、ごく少数の人しかアクセスできない堅牢なものにしているでしょうから、Google クラウドに保存されたデータを元の形として盗み出すのはほぼ不可能だと思いました。


上記が全体像のようですが、いまいちイメージがわかないと思います。
展示ブースのデモを順を追ってみてみましょう。

Step 1. 暗号化された通信を使ってデータを Googleクラウドに保存



Step 2. 複数ファイルに分割し、分割データを鍵付で暗号化



いきなりファイルを分割した上で、分割した各ファイルを別々に暗号化して、暗号鍵でロックしてしまうわけですね。

Step 3. 暗号鍵自体を、別の暗号鍵でさらに暗号化





暗号鍵自体を、別の暗号鍵で暗号化すると。つまり分割の際にアクセスを防ぐためのかけた暗号鍵を盗まれたとしても、暗号鍵自体を暗号した別の暗号鍵も一緒に得ることができないかぎり、1つの分割ファイルさえ復号化できないという念の入れようですね。

 Step 4. 分割した暗号ファイルは、それぞれ別の場所に保存


データセンター内の物理的なディスクを盗まれても、データの復元は不可能。どこの場所に保存されてるかはランダムであり、すべてを手探りで探し出すことは不可能とのこと。

また、データセンターの1つが完全破損しても、データセンター間で分割した暗号ファイル単位で相互バックアップしているので、他のデータセンターから瞬時に補完し、問題なくファイルを復元できる。

とまぁ、念には念をいれて拠点もサーバーやディスクの保存場所もランダムで複数箇所に保存されているなら、それら全部を探し出すのはちょっと不可能じゃない?と思っちゃいますね。

 Step 5. ファイルが更新された場合には?


 

ファイルを更新した場合には、別鍵で暗号化しなおし。

このあたりは使い回しをせずに鍵は毎回作り直しというのがいいですね。

疑問点:複数箇所に分散保存されたデータを高速復元可能なのは何故?


ここまで見ると、たった1つのファイルに対して世界中に散らばっているデータセンターに分散保存しているなら、そのファイルへのアクセスが遅くなるよね?だってアクセスするにはネットワーク越しに分割ファイルを集めてきて、これを復号化して元のファイルに戻すことが必要。そのためには、分割ファイルをネットワーク越しに集めてこないといけない。それってネットワークの速度にかなり依存しちゃうよね?そのあたりは大丈夫なの?という疑問が出てきます。

これについては、Google は海底ケーブルも含めて「自社」で光ファイバーを直接世界中に張り巡らせているため、自社内LANが、世界規模で構築できる出来るものすごいことをしているとのことでした。そのため、データセンターが世界中に散らばっていても、そのネットワークは Google社内 LAN になるため、高速通信できちゃうってことなのですよね。

つまりインターネット接続なしに、互いに接続できちゃうわけですので、他の影響を受けずに高速通信ができると、、それならたしかに速いでしょうね、規模が巨大すぎますけど。。。

Googleクラウドに保存されるデータは、すべて上記の対応がされている


Gmailは、添付ファイルも別途分散保存されている
動画も写真もデータもすべて分散保存されている

というから、すごいですね。

オンプレミスサーバーより、クラウドのほうが安全


これは筆者の見解です。

データは海外にある、物理ディスクを盗まれてもデータ漏洩しない仕組みとなっている。

オンプレミスでもクラウドでも、データ漏えいはユーザーの意識(アカウントの不正利用など)に起因することがほとんど

Googleアカウントは、ログイン自動不正アクセス防止機能(いつもと異なる場所、端末からアクセスすると自動的に一時ブロックする機能)、2段階認証やセキュリティキーなどによる強固な不正利用防止機能がある。

何よりオンプレミスサーバーのセキュリティ脆弱性対応には膨大なコストがかかる上に、その頻度は必ずしも高くない場合もある。またサービスの質もクラウドサービスと張り合うのはかなり辛い。結局利便性を求めてついつい無料のクラウドサービスを使ってしまう場合もあり、管理が難しい

以上から、オンプレミスサーバーで構築しないといけないケースや出来る規模もあると思いますが、クラウドサービスだからデータが盗まれるんじゃないかという点については、間違った理解かなと思います。

もちろん、クラウドサービスの提供元自体が信用できないと判断する場合はあると思います。また日本の法律が適用されないケースもあるでしょう。とはいえ、これだけクラウドサービスが身近に利用されている以上、それらと向き合わずに禁止したとしても、それを使いたい側からみたら抜け穴を探して使おうとするはず。そうではなくて、利用されることを前提として、どうしたら共存できるのかを考えたほうがいいかなと思います。

2018年11月12日 @kimipooh