💰

楽天ペイの支払いをGASでZaimアプリに自動で家計簿入力できるようにした

2024/05/24に公開
21
1

概要

Zaimは家計簿アプリで、手動で支出を入力するだけでなく、クレカや銀行口座を連携して自動で支出の把握ができて大変便利です。ただ、よく使う楽天ペイアプリの支払い連携が対応しておらず、毎回手動で入力していました。そこで、Google Apps Scriptを使って楽天ペイの利用通知メールからZaimに自動で家計簿に記入できるようにしました。

前提条件

  • Google アカウントを保有している
  • 楽天ペイ利用通知メールがGmailに届くように設定されている
  • 楽天ペイを支払いの出金元として登録している

仕様

  • 過去最新2通のメールを参照する(1通にすると1日1回実行の場合、実行時間によって取得できない情報が発生してしまうため)。
  • 対応しているメールは2種類。
    • 件名「楽天ペイアプリご利用内容確認メール」→実店舗決済
    • 件名「楽天ペイ 注文受付(自動配信メール)」→オンライン決済
  • 過去2日間のZaimへの入力情報を参照し、重複した情報であれば入力しない
  • 支払日付はメールの内容から取得するため、実際に支払った日付が入力される
  • 楽天ペイを出金元として入力
  • お店は楽天ペイの支払メールに記載されている内容を参照している
    • 実店舗決済の場合、ご利用明細の「ご利用店舗」
    • オンライン決済の場合、ご注文内容の「ご利用サイト」
  • カテゴリーと内訳はデフォルトの値を自身で設定。ただし、店舗名とカテゴリーと内訳を設定することで自動振り分けを設定できる。それ以外は手動で自分で変更する
  • メモ欄に「システムから登録」と表示される(文言はプログラムのコードの該当部分を修正することで変更可能)
  • 楽天キャッシュで支払った分のみ家計簿につける(ポイント払いの分は家計簿につけない)
  • 品目は登録できない

設定方法

Google Apps Script プロジェクトの作成

  1. Google Apps Script にアクセスし、新しいプロジェクトを作成します。

  1. プロジェクトに名前を付けます(例: mailToZaim)。

プログラムの作成

以下のコードをプロジェクトのエディタにコピー&ペーストします。

プログラムコード
const CONSUMER_KEY = PropertiesService.getScriptProperties().getProperty("ZAIM_CONSUMER_ID");
const CONSUMER_SECRET = PropertiesService.getScriptProperties().getProperty("ZAIM_CONSUMER_SECRET")
const RAKUTEN_PAYMENT_ID = parseFloat(PropertiesService.getScriptProperties().getProperty("RAKUTEN_PAYMENT_ID"));
const DEFAULT_CATEGORY_ID = parseFloat(PropertiesService.getScriptProperties().getProperty("DEFAULT_CATEGORY_ID"));
const DEFAULT_GENRE_ID = parseFloat(PropertiesService.getScriptProperties().getProperty("DEFAULT_GENRE_ID"));

// 今日の日付を取得
var date = new Date(); // 現在の日付と時刻を取得
var today = Utilities.formatDate(date, Session.getScriptTimeZone(), "yyyy-MM-dd");

// 1日前の日付を取得
var yesterday = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1);
yesterday = Utilities.formatDate(yesterday, Session.getScriptTimeZone(), "yyyy-MM-dd");

// 認証のリセット
function reset() {
  var service = getService();
  service.reset();
}

// 認証サービスの設定
function getService() {
  return OAuth1.createService("Zaim")
    // Set the endpoint URLs.
    .setAccessTokenUrl("https://api.zaim.net/v2/auth/access")
    .setRequestTokenUrl("https://api.zaim.net/v2/auth/request")
    .setAuthorizationUrl("https://auth.zaim.net/users/auth")

    // Set the consumer key and secret.
    .setConsumerKey(CONSUMER_KEY)
    .setConsumerSecret(CONSUMER_SECRET)

    // Set the name of the callback function in the script referenced
    // above that should be invoked to complete the OAuth flow.
    .setCallbackFunction("authCallback")

    // Set the property store where authorized tokens should be persisted.
    .setPropertyStore(PropertiesService.getUserProperties());
}

// OAuth Callbackの設定
function authCallback(request) {
  var service = getService();
  var authorized = service.handleCallback(request);
  if (authorized) {
    return HtmlService.createHtmlOutput("認証できました!このページを閉じて再びスクリプトを実行してください。");
  } else {
    return HtmlService.createHtmlOutput("認証に失敗");
  }
}

// GETパラメーターを作成
function encodeParams(params) {
  var encodedParams = [];
  for (var key in params) {
    encodedParams.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
  }
  return encodedParams.join("&");
}

// 過去の支払いデータを取得
function getPastData(service) {
  var url = "https://api.zaim.net/v2/home/money";

  // 日付で検索
  var params = {
    "start_date": yesterday,
    "end_date": today,
  }
  // 日付指定したい場合は日付を指定してコメントアウトを外す
  // params = {
  //   "start_date": "2024-04-20",
  //   "end_date": "2024-04-23",
  // }

  // データの取得
  var response = service.fetch(url + "?" + encodeParams(params));
  var result = JSON.parse(response.getContentText());
  // Logger.log(result); // 取得したデータを見たい場合コメントアウトを外す

  // 楽天ペイのみの支払いでフィルタリング
  var rakutenPayData = result.money.filter(function(item) {
    return item.from_account_id === RAKUTEN_PAYMENT_ID;
  });

  return rakutenPayData
}

// 楽天ペイ情報をZaimに登録(メイン関数)
function rakutenPayToZaim() {
  // Gmailで該当メールを検索
  var start = 0;
  var max = 2; // 過去いくつまでメールを遡るか
  var query = 'subject: ("楽天ペイアプリご利用内容確認メール" OR "楽天ペイ 注文受付") ';
  var threads = GmailApp.search(query, start, max);

  // 既存のデータを取得
  var service = getService();
  if (service.hasAccess()) {
    var existingData = getPastData(service)
  } else {
    var authorizationUrl = service.authorize();
    Logger.log("次のURLを開いてZaimで認証したあと、再度スクリプトを実行してください。: %s",
      authorizationUrl);
  }

  // 各楽天ペイの支払いについて登録
  for (var i = 0; i < threads.length; i++) {
    var messages = threads[i].getMessages();
    for (var j = 0; j < messages.length; j++) {
      var message = messages[j];
      var subject = message.getSubject();
      var body = message.getPlainBody();

      // ご利用日時、ご利用店舗、楽天キャッシュの金額を抽出
      if (subject == "楽天ペイアプリご利用内容確認メール") {
        var usageDate = body.match(/ご利用日時\s*([\s\S]*?)\n/)[1].trim();
        var cash = body.match(/楽天キャッシュ\s*([\s\S]*?)\s*/)[1].trim().replace(/,/g, "");
        var card = body.match(/カード\s*([\s\S]*?)\s*/)[1].trim().replace(/,/g, "");
        var shop = body.match(/ご利用店舗\s*([\s\S]*?)(?:\n|-{40})/)[1].trim();
        cash = parseInt(cash, 10)
        card = parseInt(card, 10)
        cash += card
        usageDate = usageDate.replace(/^(\d{4})\/(\d{2})\/(\d{2}).*/, "$1-$2-$3")
      } else if (subject == "楽天ペイ 注文受付(自動配信メール)") {
        var usageDate = body.match(/\d{4}-\d{2}-\d{2}/g)[0]
        var cash = body.match(/[\d,]+/g).at(-1).replace(/,/g, "").replace(//g, ""); // お支払い金額の数字を取得
        var shop = body.match(/提携サイト「(.*?)>(.*?)>(.*?)<(.*?)/)[3];
      } else {
        continue;
      }
      var isExisting = false;
      Logger.log("日付:" + usageDate + ", 支払金額:" + cash + ", お店:" + shop)

      // ポイント払いの場合はスキップ
      if (cash == 0) {
        Logger.log("ポイント払いのためスキップ");
        continue;
      }

      // 指定の日付範囲に入っていなければスキップ
      if (usageDate != yesterday & usageDate != today) continue;

      // 既存のデータと比較して、新しいデータのみを追加
      for (var k = 0; k < existingData.length; k++) {
        if (existingData[k]["date"] == usageDate && existingData[k]["amount"] == cash && existingData[k]["place"] == shop) {
          isExisting = true;
          Logger.log("既に入力済み")
          break;
        }
      }

      if (!isExisting) {
        // 登録カテゴリーシートからデータを取得
        var files = DriveApp.getFilesByName("ZAIM_DB");
        var originalData = []
        if (files.hasNext()) {
          spreadsheet = SpreadsheetApp.open(files.next());
          var originalSheet = spreadsheet.getSheetByName("登録カテゴリー");
          originalData = originalSheet.getRange(2, 1, originalSheet.getLastRow() - 1, 4).getValues();
        }

        // 登録カテゴリーシートを検索して適切なカテゴリとジャンルを設定
        var category_id = DEFAULT_CATEGORY_ID;
        var genre_id = DEFAULT_GENRE_ID;
        for (var k = 0; k < originalData.length; k++) {
          var [storeName, exactMatch, categoryId, genreId] = originalData[k];
          if ((exactMatch && storeName === shop) || (!exactMatch && shop.includes(storeName))) {
            category_id = categoryId;
            genre_id = genreId;
            break;
          }
        }

        // 支払い情報の登録
        var url = "https://api.zaim.net/v2/home/money/payment";
        var payload = {
          "category_id": category_id,
          "genre_id": genre_id,
          "amount": cash,
          "date": usageDate,
          "place": shop,
          "from_account_id": RAKUTEN_PAYMENT_ID,
          "comment": "システムから登録"
        };
        var options = {
          "method": "post",
          "payload": payload
        };
        service.fetch(url, options);
        Logger.log("支払い入力完了")
      }
    }
  }
}

// Spreadsheetに書き込み
function writeCategoriesToSpreadsheet(categories, genres, accounts) {
  const SPREADSHEET_NAME = "ZAIM_DB";
  const CATEGORY_SHEET_NAME = "カテゴリと内訳";
  const ACCOUNT_SHEET_NAME = "支払方法";
  const ORIGINAL_SHEET_NAME = "登録カテゴリー";

  // スプレッドシートを取得または作成
  let spreadsheet;
  var files = DriveApp.getFilesByName(SPREADSHEET_NAME);
  if (files.hasNext()) {
    spreadsheet = SpreadsheetApp.open(files.next());
  } else {
    spreadsheet = SpreadsheetApp.create(SPREADSHEET_NAME);
  }

  // カテゴリとジャンルのシートを作成
  let categorySheet = spreadsheet.getSheetByName(CATEGORY_SHEET_NAME);
  if (categorySheet) {
    categorySheet.clear(); // 既存のシートをクリア
  } else {
    categorySheet = spreadsheet.insertSheet(CATEGORY_SHEET_NAME);
  }

  // アカウントのシートを作成
  let accountSheet = spreadsheet.getSheetByName(ACCOUNT_SHEET_NAME);
  if (accountSheet) {
    accountSheet.clear(); // 既存のシートをクリア
  } else {
    accountSheet = spreadsheet.insertSheet(ACCOUNT_SHEET_NAME);
  }

  // オリジナルカテゴリーシートの作成
  let originalSheet = spreadsheet.getSheetByName(ORIGINAL_SHEET_NAME);
  if (!originalSheet) {
    originalSheet = spreadsheet.insertSheet(ORIGINAL_SHEET_NAME);
    var originalHeaders = ["店舗名", "完全一致", "カテゴリーID", "内訳ID"];
    originalSheet.getRange(1, 1, 1, originalHeaders.length).setValues([originalHeaders]);
  }

  // 最初のシートが存在する場合、削除する
  let defaultSheet = spreadsheet.getSheetByName("シート1");
  if (defaultSheet) {
    spreadsheet.deleteSheet(defaultSheet);
  }

  // カテゴリとジャンルのヘッダーを作成
  var categoryHeaders = ["カテゴリーID", "カテゴリー名", "内訳ID", "内訳名"];
  categorySheet.appendRow(categoryHeaders);

  // アカウントのヘッダーを作成
  var accountHeaders = ["支払ID", "支払方法"];
  accountSheet.appendRow(accountHeaders);

  // データ行を作成
  var categoryRows = [];
  categories.forEach(category => {
    var categoryGenres = genres.filter(genre => genre.category_id === category.id);
    if (categoryGenres.length > 0) {
      categoryGenres.forEach(genre => {
        categoryRows.push([
          category.id,
          category.name,
          genre.id,
          genre.name,
        ]);
      });
    } else {
      categoryRows.push([
        category.id,
        category.name,
        "",
        "",
      ]);
    }
  });
  var accountRows = accounts.map(account => [account.id, account.name]);

  // 一括で書き込み
  categorySheet.getRange(2, 1, categoryRows.length, categoryHeaders.length).setValues(categoryRows);
  accountSheet.getRange(2, 1, accountRows.length, accountHeaders.length).setValues(accountRows);

  Logger.log("カテゴリ情報、内訳、支払い方法一覧を取得しました: " + spreadsheet.getUrl());
}

// カテゴリと内訳の取得(スプレッドシート作成のメイン関数)
function getInfo() {
  var service = getService();
  if (!service.hasAccess()) {
    var authorizationUrl = service.authorize();
    Logger.log("次のURLを開いてZaimで認証したあと、再度スクリプトを実行してください。: %s",
      authorizationUrl);
  }

  // カテゴリの取得
  var categoryUrl = "https://api.zaim.net/v2/home/category";
  var response = service.fetch(categoryUrl)
  var category = JSON.parse(response.getContentText()).categories;
  var filterCategory = category.filter(item => item.mode === "payment" && item.active === 1.0)
    .sort((a, b) => a.sort - b.sort);

  // ジャンルの取得
  var genreUrl = "https://api.zaim.net/v2/home/genre";
  response = service.fetch(genreUrl)
  var genre = JSON.parse(response.getContentText()).genres;
  var filterGenre = genre.filter(item => item.active === 1.0)
    .sort((a, b) => a.sort - b.sort);

  // アカウント一覧の取得
  var accountUrl = "https://api.zaim.net/v2/home/account";
  var response = service.fetch(accountUrl);
  var account = JSON.parse(response.getContentText()).accounts;
  account = account.filter(item => item.active === 1.0)
    .sort((a, b) => a.sort - b.sort);

  // スプレッドシートに書き込み
  writeCategoriesToSpreadsheet(filterCategory, filterGenre, account);
}

Zaim APIの設定

まず、Zaim APIにログインして、コンシューマIDとコンシューマシークレットを取得します。

  1. Zaim Developers にアクセスし、Zaimアカウントでログインします。
  2. 「新しいアプリケーションを追加」をクリックし、アプリケーションを登録します。必要な情報を入力します。下記が入力例です。
    • 名称:非対応アプリの自動連携
    • サービス種:ブラウザアプリ
    • 概要:自動連携非対応アプリを自動連携する
    • 組織:(自分の名前)
    • サービスのURL(例: https://script.google.com/
    • サービスレベル:全てチェックを入れる
  3. アプリケーションを登録すると、コンシューマIDとコンシューマシークレットが表示されます。この情報は後で使用しますので、メモしておきます。

スクリプトの設定

「プロジェクト設定」から「スクリプトのプロパティ」の欄で、以下のプロパティと値を追加します。

ZAIM_CONSUMER_ID: ZaimのコンシューマID
ZAIM_CONSUMER_SECRET: Zaimのコンシューマシークレット


認証設定

こちらはZaimのAPIの認証のために必要な設定となります。
よくわからない方はとりあえず指示通りに設定すれば問題ありません。
ライブラリの「+」マークをクリックします。

スクリプトIDに以下の値を入力すると、OAuth1が検索でひっかかるのでこちらを追加します。
1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s

DB作成

関数のgetInfoを選択して、実行します。

初回はGoogleのサービスにアクセスするかの許可を聞かれるので許可します。
また、スクリプトを実行すると、初回はZaimの認証ページが表示されるので、指示に従って認証を行います。認証が成功したら、もう一度実行してみてください。詳しくはGASとZaimを連携して情報を取得するもご参考にしてください。

これで以下の3つのシートを含む「ZAIM_DB」というスプレッドシートが作成されます。

  • カテゴリと内訳:Zaimに登録されているカテゴリと内訳とそのIDが一覧表示される
  • 支払方法:支払いを入力する際の出金元の一覧とIDが表示される
  • 登録カテゴリー:自動でカテゴリと内訳を割り振れる登録シート(詳細は後ほど)

出金元とカテゴリ・内訳の設定

出金元の設定

楽天ペイを出金元とするための設定を行います。
「ZAIM_DB」のスプレッドシートの「支払方法」シートを参照します。
事前に登録されている楽天ペイの出金元を探し、支払IDを控えます。
スクリプトの設定と同様に、「プロジェクト設定」から「スクリプトのプロパティ」の欄にいき、以下のプロパティと値を登録します。

RAKUTEN_PAYMENT_ID: 楽天ペイの支払ID

カテゴリ・内訳の設定

デフォルトのカテゴリと内訳

まずは楽天ペイの支払いでデフォルトで登録するカテゴリと内訳を設定します。
よく楽天ペイで使うカテゴリと内訳があればそちらを登録しても良いですし、特になければカテゴリ:その他、内訳:その他で良いでしょう。
「ZAIM_DB」のスプレッドシートの「カテゴリと内訳」シートを参照します。
デフォルトで使用するカテゴリーIDと内訳IDを控えます。
スクリプトの設定と同様に、「プロジェクト設定」から「スクリプトのプロパティ」の欄にいき、以下のプロパティと値を登録します。

DEFAULT_CATEGORY_ID: カテゴリーID
DEFAULT_GENRE_ID: 内訳ID

よく使うカテゴリと内訳

「ZAIM_DB」のスプレッドシートの「登録カテゴリー」シートを参照します。
こちらでよく使うカテゴリーと内訳を事前に登録することができます。

※この機能を使う予定がない場合は適当な値で一行埋めないと動かない仕様になっているため適当に埋めてください。

  • 店舗名:楽天ペイのご利用明細に記載されている「ご利用店舗」
  • 完全一致:完全一致の場合は「TRUE」、チェーン店など支店名を除いたチェーン店名などを利用する場合は部分一致のため「FALSE」と入力
  • カテゴリーID:利用するカテゴリーID(「カテゴリと内訳」シートから取得)
  • 内訳ID:利用する内訳ID(「カテゴリと内訳」シートから取得)

入力例:

テスト実行

エディタ画面に戻り、関数は「rakutenPayToZaim」に設定して「実行」をクリックします。

エラーがなく実行されれば成功です。

もし直近2日間で楽天ペイによる支払いがあればZaim上に登録されるはずです。

定期実行の設定

後は定期実行の設定をするだけです。

「トリガー」をクリックします。

「トリガーを追加」をクリックします。

以下のような設定をします。
「時刻を選択」は好みの時間帯で構いません。

設定が終わったら「保存」をクリックします。
これで設定は完了です!後は実際に楽天ペイを支払った後に自動で登録されているか確認してみてください。

終わりに

これで、Google Apps Scriptを使って楽天ペイの利用通知メールからZaimに自動で家計簿を記入するプログラムの設定が完了しました。是非、試してみてください!何かわからないことや間違っていることなどあればコメント欄に書いていただければと思います。

参考URL

1

Discussion

むねむねむねむね

はじめまして、楽天ペイの支払履歴をzaimに入れたくてこのHPにたどり着きました。
現在ライブラリを入力し、getinfoの実行まで来たのですが実行結果がエラーとなってします。
もし原因など分かりましたら教えていただけますでしょうか。

むねむねむねむね

早速ご返信ありがとうございました。
Consumer Keyの設定方が間違っており、無事最後まで設定できました。
有益な情報ありがとうございました。

たなかたなか

はじめまして、1点質問がございます。
このような"
Exception: The number of rows in the range must be at least 1."というエラーはどのように対処すればよろしいでしょうか?

ひろにしひろにし

ご質問ありがとうございます。

登録カテゴリーシートのところでコケているみたいなので、
よく使うカテゴリと内訳はなにか登録されていますでしょうか?
今のプログラムがちょっとイケてない可能性があり、
もしかしたら何もカテゴリーを登録しなかったらコケる可能性があるので、
適当になにか1行追加して再度試してみていただけないでしょうか?

rarirurerolrarirurerol

大変有益な情報をありがとうございます。
ご指南の通り設定も行ったように思え、実行ログ上も問題がないようなのですがzaim上に反映されてきません。何か確認すべきことがあればご指南ください。

実行ログ
21:18:32 お知らせ 実行開始
21:18:33 情報 日付:2025-01-05, 支払金額:3703, お店:X
21:18:33 情報 日付:2023-11-18, 支払金額:565, お店:Y
21:18:35 お知らせ 実行完了

rarirurerolrarirurerol

設定以前の支払いが反映されて居ないだけでした。新規に購入した分は反映されており、無事に動作しております。
大変失礼しました。

ひろにしひろにし

返信遅れました、失礼しました。
仕様に書いてあるとおり、プログラムそのままですと直近2日分しか反映されないようになっています。
無事動いてよかったです!

よわよわコードマンよわよわコードマン

お世話になります。
楽天キャッシュを元に支払いをした場合の、楽天Payの履歴をzaimに同期したく、この記事を参照させていただきました。
当方、プログラミングは完全に初心者となります。

動作テストまで実施をし、「実行完了」のLogも出力されているのですが、
zaim側に作成した楽天Payの口座に履歴が反映されないため、ご質問をさせていただきます。

詳細

私は2024/10/18より楽天キャッシュを支払元にした決済を始めたため、この記事に記載のコードに対して、以下のように変更をかけました。

  • 66~69 行目をコメントアウト
  • 71~74 行目のコメントアウトを解除
  • 71行目にVarを追記
  • "start_date" に 2024-10-18 を指定
  • "end_date" に 2025-01-17 を指定
  • 93行目の値を50に変更(2024-10-18のメールまで遡るため)

この状態で実行すると、2024-10-18より少し以前の決済も含めてLog出力され、「実行完了」のLogが出力されました。
しかし、zaim側の口座に取引履歴が反映されない状態となっております。

楽天Payの口座のIDが合っている事と、zaimアプリ側でのオンライン同期は確認済みとなりますが、
その他にコードに対して必要な変更がある場合、コードが読み解けず詰まっております。
解決方法について心当たりがございましたら、ご教授をお願いしたく存じます。

ちなみに、zaimアプリはAndroid版となります。

(なお、一度2024-10-18以降の履歴を取り込めたら、記事通りのコードに戻して運用していく予定です)

ご確認よろしくお願い致します。

ひろにしひろにし

ご質問ありがとうございます。
ぱっと見問題ないように見えます。
まず根本原因を把握したいのですが、一度元のコードに戻していただき、
楽天ペイでどこかで支払いした場合に、ちゃんと2日前までの情報がzaimに反映されるかを確認していただけないでしょうか?
変更箇所が問題なのか、そもそもzaimへの登録がうまくいっていないのかを把握するためです。

よわよわコードマンよわよわコードマン

ご返信誠にありがとうございます。
大変助かります。

最近、期間限定ポイントを使うために、一時的に支払元を楽天キャッシュではなくしていたため、元のコードでは情報の取得対象とならず、軽い動作確認だけしてコードを変えてしまい上記のご質問となりました。
お手数おかけしまして申し訳ございません。

まずは支払元を楽天キャッシュにした決済を行ってみて、元のコードでzaimに反映されるかを試してみます。
(追ってコメントさせていただきます)

ちなみにここからは補足情報となりますが、
先日、元質問の改変したコードで何回か動作確認をしていたのですが、
既にzaimに反映済みの重複データは本来 "既に入力済み" とログを吐いてスキップされる仕様かと思います。
ですがこちらのログ( "既に入力済み" )は何度実行しても吐かれることはございませんでしたので、補足として記載させていただきます。

なお、 "ポイント払いのためスキップ" のログは吐かれておりました。

ここまでの情報と、ある程度関数の定義を追ってみた感覚から、142行目あたりが怪しいのではと勝手に考えているのですが、いかんせん言語の種類すら分かっていない始末でして・・・
もし心当たりがございましたら、ご教授いただけますと幸いです。

まずは一旦、ご助言ありがとうございました。

よわよわコードマンよわよわコードマン

五月雨式にて申し訳ございません。

色々と試行錯誤したのですが、
142行目(指定の日付範囲に入っていなければスキップの箇所)をコメントアウトすることで、zaimへ履歴が登録され、解決いたしました。
大変お騒がせいたしました。

レアパターンかもしれませんが、私のように楽天Payの支払元を途中から楽天キャッシュにしたパターンの方で、最初だけその日付から履歴を取得したい!という方は、
142行目のコメントアウト及び、Gmailで登録したい(遡りたい)メールの数を数えて93行目の数値を合わせるのが良さそうです。

(それより前の楽天カードを支払元にしていた時期は、カード側のzaim連携で詳しい明細まで見られるので取り込まない形としました)

私は楽天キャッシュ変更後の履歴を取り込めましたので、この記事に記載通りのコードに戻し、今後の使用履歴を連携させていく予定です。

大変お世話になりました。
ありがとうございました!

ひろにしひろにし

色々と試行錯誤していただき解決したようで良かったです。
ただ、ご指摘の通り楽天キャッシュの支払い分しか家計簿としてつけられない点が記事にはなく、
ソースを読まないと分からないようになっていたので、
仕様にその旨を追記しました。

この度は貴重な情報の提供をありがとうございました!

しいたけしいたけ

はじめまして。Zaim利用者です。
おかげさまで、楽天キャッシュの利用情報がZaimに自動で登録できない悩みを解消することができました。
大変有用な情報をまとめてくださり誠にありがとうございます!

1点だけお願いです。
よく使うカテゴリと内訳のところ、シートに1行追加しないとエラーになりましたので、その旨記事内でフォローいただけると幸いです。

その他、特に引っかかることもなく、スムーズに登録でき、大変感謝しております。
ささやかながら、バッジをお贈りさせていただきました。今後の家計簿ライフにお役立てください。

ひろにしひろにし

コメントありがとうございます。
そして別の方からも同様のコメントをいただいており、おっしゃる通りよく使うカテゴリと内訳は一行入れないと動かなく、いけてない仕様になっていました。
本当はコードを修正したいですが一旦今のままとし、記事に追記しました。
ご指摘ありがとうございます。

そしてバッジをお贈りいただき大変ありがとうございます!
正直このレベルのものでもらえると思っていなかったので誰かの役に立てていると思うと大変嬉しい限りです。
今後もお互いに良い家計簿ライフを送っていきましょう!

もりろもりろ

はじめまして。
こちらの記事のおかげで自動入力が叶いました。ありがとうございます。
全くの無知で申し訳ないのですが、自動入力後のzaimではおそらく「かんたん入力」で記入されており、後から品目別に編集することができないようでした。
自動入力の際は特に内訳が分かれていなくてもよいのですが、後からzaim側で内訳を編集できるとよいなと思っております。
何か良い案はありますでしょうか?

ひろにしひろにし

ご質問ありがとうございます。
普段品目をいじらないので全く気にしていませんでしたが、こんな違いがあるのは知りませんでした。
ご指摘いただきありがとうございます。
私の方で調べた限り自動入力でそもそも品目を入力することができない仕様に感じます。
現在自動入力で登録できる項目が公式APIですと下記となっており、品目に該当するものがないため

*mapping: 1
*category_id: category id for payment *1
*genre_id: genre id for payment *2
*amount: amount without decimal point *3
*date: date of Y-m-d format (past/future 5 years is valid)
from_account_id: account id for payment *4
comment: comment (within 100 characters)
name: product name (within 100 characters)
place: place name (within 100 characters)
*required item

なので私の理解だと「現状品目登録ができない」が回答となります。
ただ、どうしても気になるのであればZaim担当者に問い合わせてみても良いかもしれません。

よろしくお願いいたします。

※一応今回のご指摘を受け、本記事の仕様に品目は登録できない旨を追記します。

タツママタツママ

プログラミング超初心者ですが、楽天ペイの支払いを取り込みたくてこちらにたどり着きました。

rakutenPayToZaim を実行すると次のようなエラーが出てしまうのですが
どんな原因が考えれますでしょうか

TypeError: Cannot read properties of null (reading '1')
rakutenPayToZaim @ コード.gs:118

118行目は
var cash = body.match(/楽天キャッシュ\s*([\s\S]?)\s円/)[1].trim().replace(/,/g, "");
と書かれている行になります

最近の支払いではキャッシュは使っておらず、ポイントのみで支払いしたせいでしょうか?

あと一息でゴールにつけそうなのに残念で。。。
もしよろしければご教示いただけないでしょうか
よろしくお願いいたします

ひろにしひろにし

ポイント払いの場合はスキップされるので影響はないです。
今回の場合、メールの内容が読み込めてない可能性があります。
個人情報のところは消していただくとかでも良いので
メールの画像キャプチャまたは本文を一部記載していただければ
何が問題かわかるかもしれません。

タツママタツママ

ご返信ありがとうございます。
前回の楽天ペイの買い物から2日経過したため、今日新たに楽天ペイで支払いをしてきました。今回は楽天キャッシュを使用しましたところ、次のようなエラーになりました。
購入確認のメールも添付させていただきます。よろしくお願いいたします。

タツママタツママ

追伸です。お世話になっております。今日ZAIMを確認しましたら、ZAIMへの書き込みは正常にできていました。エラーメッセージは出てしまいますが、この状態でトリガーの設定をしても大丈夫でしょうか?お手数をお掛けしますがよろしくお願い致します。