Google App Script 自動化

【GAS】楽天ペイの利用情報をカレンダーに登録

はじめに

なるちゃん

ねえ、おとん、

楽天ペイって便利だけど、いつ使ったか忘れちゃって、使い過ぎになりがちじゃない?

そお?じゃあ、いつどれだけ使ったのかをカレンダーに登録して確認できるようにしてみる?

関谷さん
なるちゃん

そんなことできるの?

ちょっとやってくれる?

ということで、楽天ペイを使って買い物をした時に、買い物をした時間に使った金額と共にカレンダーに登録する仕組みを作りました。

Google Apps Scriptの活用例として参照ください。

対象読者

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

対象読者

  • 楽天ペイを使うことがある
  • 楽天ペイの利用確認メールをGmailで受け取っている
  • 楽天ペイ利用情報をGoogleカレンダーに自動登録させたい

楽天ペイ情報のカレンダー登録

まず、ほとんどの処理はAmazonの注文情報処理や、楽天市場注文処理と同様です。

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

  • Gmailでメールを抽出する際の検索文字が、楽天ペイからの注文確認メールを抽出する
  • カレンダーに登録する文字が「RPay+利用金額」である
  • カレンダーの詳細に登録する内容の抽出方法が楽天ペイ利用確認メール用に特化している
  • どこで使ったのかがわかるように、登録する詳細内容に利用場所をメモに追加する

処理概要

楽天ペイを利用すると以下のような利用明細をメールで受け取ることができます。

Googleカレンダーに利用内容を登録するために、以下の処理を考えます。

  • 楽天ペイからの利用確認メールを抽出
  • 未処理のメールを抽出
  • 楽天ペイの利用額と利用店舗を抽出
  • カレンダーに利用確認メールの内容を登録
  • 利用確認メールに処理済みラベルを付ける

そして、この処理を定期的に行わせます。

未処理メールの抽出

楽天ペイからの注文確認メールで、未処理のメールの抽出は以下の検索文字列で実現します。

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

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

// GMail検索文字列
var SEARCH_QUERY = 'is:unread -label:' + LABEL + ' from:no-reply@pay.rakuten.co.jp subject:楽天ペイアプリご利用内容確認メール';

処理済みを識別するために、処理完了後に該当メールのラベルに「自動処理済」を付けます。

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

  • 未読であること(is:unread)
  • 「自動処理済」のラベルが付いていないこと(-label:自動処理済)
  • 楽天ペイからのメールであること(from:no-reply@pay.rakuten.co.jp)
  • 楽天ペイからの利用確認メールであること(subject:楽天ペイアプリご利用内容確認メール)

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

カレンダー登録

カレンダーのタイトルは「RPay+利用金額」とします。

Googleカレンダーの枠に入るような長さにしましたが、楽天ペイであることがわかればよいだけなので、好みで変えてください。

カレンダーに登録する詳細内容には楽天ペイの利用場所を登録します。

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

function registerCalendar(calendar, startTime, endTime, payStore, amount){
  if (startTime && endTime && payStore && amount) {
    var title = 'RPay ' + amount;

    // カレンダーに追加
    if(checkExist(calendar, startTime, endTime, title) == false){
      var options = {
        description : payStore
      }
      var event = calendar.createEvent(title, startTime, endTime, options);
      event.setColor(CalendarApp.EventColor.GREEN);
      event.removeAllReminders();   // 利用実績なので通知しない
      Logger.log('【登録】\n利用店舗:'+payStore + '\n開始:'+startTime + '\n終了:'+endTime + '\n金額:'+amount);
    }
  }  
}

登録済み情報チェック

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

そして、同じイベントの登録がない場合に、カレンダーに登録します。

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に利用した時間に以下のイベントが作成される。
 * 「RPay(金額)円」
 * 
 * 2021/09/14 Created by N.Sekiya
 */

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

// GMail検索文字列
var SEARCH_QUERY = 'is:unread -label:' + LABEL + ' from:no-reply@pay.rakuten.co.jp subject:楽天ペイアプリご利用内容確認メール';

// 検索文字列
var PAY_DATE = 'ご利用日時  ';
var PAY_AMOUNT = 'お支払金額  ';
var PAY_STORE = 'ご利用店舗  ';

function registRPayUsageToCalendar() {

  // デフォルトカレンダーを取得
  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の本文を取得する
      //Logger.log(body);

      var startTime = null;       // 利用時間
      var endTime = null;         // 利用時間+10分
      var amount = null;          // 支払額
      var payStore = null;        // 利用店舗

      var rows = body.split('\n');// 1行ごとに処理するために改行で分割する      
      for (var i in rows) {
        var row = rows[i];

        if(row.indexOf(PAY_DATE) >= 0){
          var start = row.replace(PAY_DATE, '');
          var tmp = start.split(' ');
          var yymmdd = tmp[0].substr(2, 10);
          var hhmmss = tmp[1];
          var yymmdd_hhmmss = yymmdd + ' ' + hhmmss;
          startTime = new Date(yymmdd_hhmmss);
          endTime = new Date(startTime.getTime() + 10 * 60000); // 終了時刻取得
          //Logger.log('startTime: ' + startTime + '\nendTime: ' + endTime);
        }
        else if(row.indexOf(PAY_AMOUNT) >= 0){
          amount = row.replace(PAY_AMOUNT, '');
          amount = amount.substr(2);
          //Logger.log('amount: ' + amount);
        }
        else if(row.indexOf(PAY_STORE) >= 0){
          payStore = row.replace(PAY_STORE, '');
          payStore = payStore.substr(2);
          //Logger.log('payStore: ' + payStore);
        }
      }

      // Googleカレンダーに登録
      //Logger.log('【メール】\n利用店舗:'+payStore + '\n開始:'+startTime + '\n終了:'+endTime + '\n金額:'+amount);
      registerCalendar(calendar, startTime, endTime, payStore, amount);

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

/*
 * Google Calendarに登録
 */
function registerCalendar(calendar, startTime, endTime, payStore, amount){
  if (startTime && endTime && payStore && amount) {
    var title = 'RPay ' + amount;

    // カレンダーに追加
    if(checkExist(calendar, startTime, endTime, title) == false){
      var options = {
        description : payStore
      }
      var event = calendar.createEvent(title, startTime, endTime, options);
      event.setColor(CalendarApp.EventColor.GREEN);
      event.removeAllReminders();   // 利用実績なので通知しない
      Logger.log('【登録】\n利用店舗:'+payStore + '\n開始:'+startTime + '\n終了:'+endTime + '\n金額:'+amount);
    }
  }  
}

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

  // イベントリスト取得
  var events = calendar.getEvents(registStart, registEnd);
  for(const event of events){
    var title = event.getTitle();
    //Logger.log('title:' + title);
    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分おきにします。

最後に

Amazon、楽天市場、Google Play、楽天ペイの情報をカレンダーに登録すると、結構ごちゃごちゃしてきます。

他の重要なイベントと簡単に区別できるように、カレンダーを分けたほうが良いかもしれません。

この場合、デフォルトカレンダーではなく、特定のカレンダーを開くように修正することで実現できます。

難しい処理ではないので、試しに修正してみるのもよいかと思います。

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

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