【Google Apps Script初心者でも出来る】GoogleApps(gmail)の受信メールをLAMP環境で処理する方法


ラクスルの利根川です。

ラクスルでは メール・カレンダー・ドキュメントにGoogle Apps for Business を利用しています。その中でも、Google Apps Script を活用するとさらに業務の効率化が可能ですので、
今回はその活用例を紹介します。

この処理を開始した背景

ラクスルでは各社員のメール以外にもカスタマーサポートの際に印刷をご注文のお客様とメールのやりとりもしばしば発生します。 > ラクスルの注文の流れ

2年前のサービス開始当初はカスタマーサポートも数名だったので
Gmail のメーリングリストに届くメールに対応していればよかったのですが、
カスタマーサポートチームのメンバーも増え(現在も絶賛採用中です! ラクスル採用サイト )、
担当の割り振りをしたい/対応漏れを予防しなくては/メール業務だけGmailだと非効率 等々の理由で
その他のカスタマーサポート業務でも使用している LAMP 環境と連携させることにしました。

実装方法

おおまかには5つのステップです。
1. Gmail のFilter にて Label を付ける
2. Google AppsのScriptを作成
3. サーバー側よしなに受け取って対応する
4. Google Appsでデバッグ・実行する
5. Google AppsのScriptから毎分Gmailを確認して未読のメールをEndPoint にpostする

1つずつ説明していきます。

1. Gmail のFilter にて Label を付ける

対象とするメールにフィルタを作成します。
後半のStepで既読/未読で連携するメールを選択するので可能であれば、一つアカウントを追加したほうがベターです。
add_gmail_filter

2. Google AppsのScriptを作成

サンプルコードをgistにおいておきましたので、その流れを解説します。

まずは、初期設定をします。

//Define

//EndPoint URL
var endpoint = "https://your-admin-domain.com/endpoint.php";
//BasicAuthForEndPoint
var unamepass = "username:password";
//Label
var LabelIn = "ToAdmin";
var LabelArchive = "ToAdmin/Archive”;

 

以下は中身の簡単な解説ですが。

弄りたい時はGoogleの公式ドキュメントがわかりやすいです。
対象となるラベル内をスレッド単位で処理します。

//GetThreads from label:ToAdmin
var label = GmailApp.getUserLabelByName(LabelIn);
var threads = label.getThreads();
for (var i=0; i < threads.length; i++) {
    //スレッド別処理
}

 

スレッド内のメッセージのうち未読のものだけを処理します。

    for (var j=0; j < messages.length; j++) {
      var message   = messages[j];
      if (!message.isUnread()) {
        continue;
      }
      //メッセージ別処理
    }

 

件名、本文、Fromを変数に格納しBasic認証のheaderを付加します。

var subject   = threads[i].getFirstMessageSubject();
var from      = message.getFrom();
var body      = message.getBody();
var payload = {
  "subject"  : subject,
  "body"     : body,
  "from"     : from,
};
var digestfull = "Basic "+ Utilities.base64Encode(unamepass);
var options = {
  "method"   : "post"
  ,"payload"  : payload
  ,"headers"  : {"Authorization":digestfull}
};

 

UrlFetchApp.fetch() メソッドでHTTP Requestを実行出来ます。
UrlFetchAppについてもドキュメントが詳しいです。
(responseのstatus code等判定したほうがベターですね)
実行後、メッセージを既読にしています。

var response = UrlFetchApp.fetch(endpoint, options);
message.markRead();

 

スレッドからラベルも外し、アーカイブ用の別ラベルを付与しています。

//LabelToArchive
var labelToMove = GmailApp.getUserLabelByName(LabelArchive);
labelToMove.addToThreads(threads);
label.removeFromThreads(threads);

3. サーバー側よしなに受け取って対応する

phpなら$_POSTからよしなに処理しましょう。

<?php
var_dump($_POST);
//array(3) {
//  ["subject"]=>
//  string(6) "件名"
//  ["body"]=>
//  string(6) "本文"
//  ["from"]=>
//  string(15) "from@raksul.com"
//}

4. Google Appsでデバッグ・実行する

動作の検証は
関数の選択 → forwardToAdmin → 虫マークのデバッグ
で実行できます。
スクリーンショット 2014-07-20 19.04.46

breakpointも設定でき、各変数の値も下段に表示されます。

スクリーンショット 2014-07-20 19.06.54

5. Google AppsのScriptから毎分Gmailを確認して未読のメールをEndPoint にpostする

問題なく動作することを確認したら、
リソース → 現在のプロジェクトのトリガー → 新しいトリガーを追加 → 分タイマー → 1分ごと
で毎分実施してくれます。

スクリーンショット 2014-07-20 19.08.42

その他の処理方法

実は、このコードを書いたのは1年以上前なのですが、
最近少し改修があったので、Blogの記事化をしました。

ドキュメントを探しながら気づいたのですが、
実はGoogleApps側にJDBCドライバーがあり、これだとDBに直接Insert出来ますね。> ドキュメント

この場合、validationの設計がGoogle Apps Script上で必要ですし、
他のLAMP環境が中心の場合、Google Apps Scriptにあまり多くのコードを置くのも
コード資産が分散してしまうので、悩ましいところですね。

PR

・TVCMも放送中。1枚1.1円からのチラシや100枚500円のワンコイン名刺を提供中。
<ネット印刷のラクスル>
・ラクスルでは新しいメンバーを採用中!<ラクスル採用サイト>