Google App Script 自動化

【GAS】楽天市場の注文情報をカレンダーに登録

はじめに

Amazonの注文情報をGoogleカレンダーに登録できるようにしたら意外に便利で、楽天市場版も欲しくなりました。

そして、楽天市場の注文情報もGoogleカレンダーに登録する処理が欲しくなりました。

ここで紹介する内容は、以下の条件を満たす方が対象となります。

対象読者

  • 楽天市場で購入することがある
  • 楽天市場からの注文確認メールをGmailで受信している
  • 楽天市場の注文確認メールの内容をGoogleカレンダーに自動登録させてみたい

では、どのように実装するのかを見ていきましょう。

楽天市場の注文内容をカレンダー登録

Amazonの注文情報をGoogleカレンダーに登録するのと同様の処理を行います。

主な違いは以下の3点です。

  • Gmailでメールを抽出する際の検索文字が、楽天市場からの注文確認メールの抽出になる
  • イベントに登録する文字が「楽天注文」となる
  • イベントの内容説明に登録する文章の切り取り開始位置を変える

では、見ていきましょう。

処理概要

まず、以下のような処理を実装することを考えます。

  • 楽天市場から注文確認メールを受信
  • 未処理のメールを抽出
  • カレンダー注文確認メールの内容を登録
  • 注文確認メールに処理済みラベルを付ける

そして、この処理を定期的に実行するようにします。

未処理メールの抽出

最初に、処理対象となるメールを抽出する処理を考えます。

抽出するメールは、楽天市場からの注文確認メールでかつ、未処理のメールとなります。

この場合のメールの抽出については、以下の検索文字列で実現できます。

// 処理済み後に付けるラベル名
var LABEL = '自動処理済';

// GMail検索文字列(楽天市場からの注文確認メール)※未読でラベルなしが条件
var SEARCH_QUERY = 'is:unread -label:' + LABEL + ' from:order@rakuten.co.jp 【楽天市場】注文内容ご確認(自動配信メール)';

また、メールの抽出条件の構文は、Gmailの抽出条件に設定できる構文と同じです。

処理が完了したら、処理済みであることがわかるようにメールに「自動処理済」のラベルを付けます。

そのため、抽出条件は以下の4つとなります。

  • 未読であること(is:unread)
  • 「自動処理済」のラベルが付いていないこと(-label:自動処理済)
  • 楽天市場からのメールであること(from: order@rakuten.co.jp)
  • 注文確認メールが確認できること(【楽天市場】注文内容ご確認(自動配信メール))

Gmailへのアクセス方法については以下の記事を参照ください。

イベント内容説明

Googleカレンダーでイベントの詳細を表示させたら、以下のように注文確認メールの内容が確認できるようにします。

以下にコードの抜粋を示します。

メールのプレーンテキストをbodyに取得し、改行で区切った文字列をrowsに格納し、その後1行ごとに処理します。

その中で「この度は楽天市場内のショップ」という文字列が出現する行以降を詳細内容に登録するためにcontentsに格納します。

// 検索文字列
var CUT_START = 'この度は楽天市場内のショップ';

for(var k in threads){
  var thread = threads[k]
  var messages = thread.getMessages();
  for (var j in messages){
    var message = messages[j];
    var body = message.getPlainBody();   // HtmlメールからPlain textの本文を取得する
    var contents = null;      // 登録内容
    var flgAdd = 0;           // 追加フラグ(0:追加しない、1:追加する)

    // 注文メールの内容確認
    var rows = body.split("\n");
    for (var i in rows) {
      var row = rows[i];

      // 切り取り開始位置確認
      if (row.indexOf(CUT_START) >= 0) {
        flgAdd = 1;
      } 

      // CUT_STARTから後を取得する
      if(flgAdd){
        if(contents == null){
          contents = row;
        }
        else{
          contents = contents + row + '\n';
        }
      }
    }
    // contentsの内容を確認するためのコンソール出力
    Logger.log(contents); 
  }
}

上記コードは説明のために抜粋したものなので、このままでは動作しません。

コードの全体については、「全てのコード」を確認ください。

カレンダー登録

イベントのタイトルは「楽天注文」とします。※好みで変えてください。

イベントに登録する詳細内容には、楽天市場からの注文確認メールの内容を登録します。

また、イベントの色は緑色にしていますが、ここも好きな色を設定してください。

function registerCalendar(calendar, startTime, endTime, contents){
  if (startTime && endTime && contents) {
    var title = '楽天注文';

    // カレンダーに追加
    if(checkExist(calendar, startTime, endTime, title) == false){
      var options = {
        description : contents
      }
      var event = calendar.createEvent(title, startTime, endTime, options);
      event.setColor(CalendarApp.EventColor.GREEN);
      event.removeAllReminders();   // 利用実績なので通知しない
    }
  }  
}

登録済み情報チェック

カレンダーに追加する前に、同じ時間の同じタイトルで、既に登録があるかチェックします。

登録できるのは同じイベントがない場合とします。

function checkExist(calendar, registStart, registEnd, registTitle){

  // イベントリスト取得
  var events = calendar.getEvents(registStart, registEnd);
  for(const event of events){
    var title = event.getTitle();
    if(title.indexOf(registTitle) >= 0){
      return true;    // イベント登録済み
    }
  }
  return false;  // イベント未登録
}

この関数では、開始終了時間とタイトルが同じイベントがあるかチェックし、以下のように値を返します。

  • イベント登録済み:true
  • イベント未登録:false

処理済みラベル

処理済みを識別するために既読にする方法もあるのですが、それだとメールをチェックした時に気づくことができず見落とす可能性が高くなります。そのため、処理済みメールの識別には「自動処理済」のラベルを付けることにします。

この「自動処理済」のラベルについては、好みで変更することができます。

var LABEL = '自動処理済';

function putLabel(thread){
  var label = GmailApp.getUserLabelByName(LABEL);
  if(label){
    thread.addLabel(label);
    Logger.log('既存ラベル使用');
  }
  else{
    var newlabel = GmailApp.createLabel(LABEL);
    thread.addLabel(newlabel);
    Logger.log('新規ラベル追加');
  }
}

「自動処理済」のラベルがない場合は、新規にラベルを作る仕組みとしています。

実行結果

全てのコードの準備が終わったら、過去に楽天市場で注文したメールを未読にしてスクリプトを実行してみましょう。

Googleカレンダーには以下のように登録されます。

イベントをクリックすることで、詳細内容を確認することができます。

全てのコード

/*
 * 楽天市場の注文内容をGoogle Calendarに登録する
 * 
 * Google Calenderに以下のフォーマットで終日イベントが作成される。
 * 「楽天注文」
 * 
 * 2021/09/15 Created by N.Sekiya
 */

// 処理済み後に付けるラベル名(ラベルが存在しなければ自動的に作られる)
var LABEL = '自動処理済';

// GMail検索文字列(楽天市場からの注文確認メール)※未読でラベルなしが条件
var SEARCH_QUERY = 'is:unread -label:' + LABEL + ' from:order@rakuten.co.jp 【楽天市場】注文内容ご確認(自動配信メール)';

// 検索文字列
var CUT_START = 'この度は楽天市場内のショップ';

function registOrderInformationToCalendar() {

  // デフォルトカレンダーを取得
  var calendar = CalendarApp.getDefaultCalendar();

  var threads = GmailApp.search(SEARCH_QUERY, 0, 1);
  if (threads.length === 0) {
    Logger.log('メールが見つかりません');
    return;
  }

  for(var k in threads){
    var thread = threads[k]
    var messages = thread.getMessages();
    for (var j in messages){
      var message = messages[j];
      var body = message.getPlainBody();   // HtmlメールからPlain textの本文を取得する
      var startTime = message.getDate();
      var endTime = new Date(startTime.getTime() + 10 * 60000);
      //Logger.log("body=" + body);

      var contents = null;      // 登録内容
      var flgAdd = 0;           // 追加フラグ(0:追加しない、1:追加する)

      // 注文メールの内容確認
      var rows = body.split("\n");
      for (var i in rows) {
        var row = rows[i];

        // 切り取り開始位置確認
        if (row.indexOf(CUT_START) >= 0) {
          flgAdd = 1;
        } 

        // CUT_STARTから後を取得する
        if(flgAdd){
          if(contents == null){
            contents = row;
          }
          else{
            contents = contents + row + '\n';
          }
        }
      }
      //Logger.log(startTime);
      //Logger.log(endTime);
      //Logger.log(contents);

      // Googleカレンダーに登録
      registerCalendar(calendar, startTime, endTime, contents);

      // 処理済みメールとしてラベルを付ける
      putLabel(thread);
    }
  }
}

/*
 * Google Calendarに登録
 */
function registerCalendar(calendar, startTime, endTime, contents){
  if (startTime && endTime && contents) {
    var title = '楽天注文';

    // カレンダーに追加
    if(checkExist(calendar, startTime, endTime, title) == false){
      var options = {
        description : contents
      }
      var event = calendar.createEvent(title, startTime, endTime, options);
      event.setColor(CalendarApp.EventColor.GREEN);
      event.removeAllReminders();   // 利用実績なので通知しない
    }
  }  
}

/*
 * 登録済み情報があるかチェック
 */
function checkExist(calendar, registStart, registEnd, registTitle){

  // イベントリスト取得
  var events = calendar.getEvents(registStart, registEnd);
  for(const event of events){
    var title = event.getTitle();
    if(title.indexOf(registTitle) >= 0){
      return true;    // イベント登録済み
    }
  }
  // イベント未登録
  return false;
}

/*
 * 処理済みとしてスレッドにラベルを付ける
 * LABELで指定されるラベルが存在しない場合は作成する
 */
function putLabel(thread){
  var label = GmailApp.getUserLabelByName(LABEL);
  if(label){
    thread.addLabel(label);
    Logger.log('既存ラベル使用');
  }
  else{
    var newlabel = GmailApp.createLabel(LABEL);
    thread.addLabel(newlabel);
    Logger.log('新規ラベル追加');
  }
}

繰返し実行

正しく動作することを確認したら、繰り返し実行できるよう設定します。

繰り返し実行には、トリガーの設定を行います。設定方法については、以下の記事を参照ください。

繰り返し実行する間隔は、急ぐ必要のない処理なので5分おきにします。

最後に

更に、注文確認内容をGoogleスプレッドシートに自動的に追加すると、購入リストを手動で作らなくて済むようになりますね。

この注文内容を自動的にスプレッドシートに追加する処理についてはこちらで公開しています。

想像力を膨らませると、Google Apps Scriptで出来ることが広がります。

みなさまも、いろいろと試してみてはいかがでしょうか。

では、今日も良い一日を。

-Google App Script, 自動化
-, , , , ,