楽天ペイの支払いをGASでZaimアプリに自動で家計簿入力できるようにした
概要
Zaimは家計簿アプリで、手動で支出を入力するだけでなく、クレカや銀行口座を連携して自動で支出の把握ができて大変便利です。ただ、よく使う楽天ペイアプリの支払い連携が対応しておらず、毎回手動で入力していました。そこで、Google Apps Scriptを使って楽天ペイの利用通知メールからZaimに自動で家計簿に記入できるようにしました。
前提条件
- Google アカウントを保有している
- 楽天ペイ利用通知メールがGmailに届くように設定されている
- 楽天ペイを支払いの出金元として登録している
仕様
- 過去最新2通のメールを参照する(1通にすると1日1回実行の場合、実行時間によって取得できない情報が発生してしまうため)。
- 対応しているメールは2種類。
- 件名「楽天ペイアプリご利用内容確認メール」→実店舗決済
- 件名「楽天ペイ 注文受付(自動配信メール)」→オンライン決済
- 過去2日間のZaimへの入力情報を参照し、重複した情報であれば入力しない
- 支払日付はメールの内容から取得するため、実際に支払った日付が入力される
- 楽天ペイを出金元として入力
- お店は楽天ペイの支払メールに記載されている内容を参照している
- 実店舗決済の場合、ご利用明細の「ご利用店舗」
- オンライン決済の場合、ご注文内容の「ご利用サイト」
- カテゴリーと内訳はデフォルトの値を自身で設定。ただし、店舗名とカテゴリーと内訳を設定することで自動振り分けを設定できる。それ以外は手動で自分で変更する
- メモ欄に「システムから登録」と表示される(文言はプログラムのコードの該当部分を修正することで変更可能)
- 楽天キャッシュで支払った分のみ家計簿につける(ポイント払いの分は家計簿につけない)→ただし現状オンライン決済は楽天キャッシュと楽天ポイントは両方家計簿につけられないので要注意(楽天カード決済のみ対応)
- 品目は登録できない
設定方法
Google Apps Script プロジェクトの作成
- Google Apps Script にアクセスし、新しいプロジェクトを作成します。
- プロジェクトに名前を付けます(例:
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*(?:¥([\d,]+)|([\d,]+)円)/);
cash = (cash[1] || cash[2]).replace(/,/g, "");
var card = body.match(/カード\s*(?:¥([\d,]+)|([\d,]+)円)/);
card = (card[1] || card[2]).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 cashMatch = body.match(/(?:¥([\d,]+)|([\d,]+)円)/g).at(-1);
var cash = cashMatch.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とコンシューマシークレットを取得します。
- Zaim Developers にアクセスし、Zaimアカウントでログインします。
- 「新しいアプリケーションを追加」をクリックし、アプリケーションを登録します。必要な情報を入力します。下記が入力例です。
- 名称:非対応アプリの自動連携
- サービス種:ブラウザアプリ
- 概要:自動連携非対応アプリを自動連携する
- 組織:(自分の名前)
- サービスのURL(例:
https://script.google.com/
) - サービスレベル:全てチェックを入れる
- アプリケーションを登録すると、コンシューマ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に自動で家計簿を記入するプログラムの設定が完了しました。是非、試してみてください!何かわからないことや間違っていることなどあればコメント欄に書いていただければと思います。
Discussion
はじめまして、楽天ペイの支払履歴をzaimに入れたくてこのHPにたどり着きました。

現在ライブラリを入力し、getinfoの実行まで来たのですが実行結果がエラーとなってします。
もし原因など分かりましたら教えていただけますでしょうか。
お問い合わせありがとうございます!
ちょっとこのログだけだとなんとも言えませんが、できる範囲で回答します。
Consumer Keyは設定されていますでしょうか?
また、初回API利用時は認証が必要なのですが下記参考のURLのようにその認証はされましたでしょうか?
GAS(実行)
早速ご返信ありがとうございました。
Consumer Keyの設定方が間違っており、無事最後まで設定できました。
有益な情報ありがとうございました。
はじめまして、1点質問がございます。
このような"
Exception: The number of rows in the range must be at least 1."というエラーはどのように対処すればよろしいでしょうか?
ご質問ありがとうございます。
登録カテゴリーシートのところでコケているみたいなので、
よく使うカテゴリと内訳はなにか登録されていますでしょうか?
今のプログラムがちょっとイケてない可能性があり、
もしかしたら何もカテゴリーを登録しなかったらコケる可能性があるので、
適当になにか1行追加して再度試してみていただけないでしょうか?
大変有益な情報をありがとうございます。
ご指南の通り設定も行ったように思え、実行ログ上も問題がないようなのですがzaim上に反映されてきません。何か確認すべきことがあればご指南ください。
実行ログ
21:18:32 お知らせ 実行開始
21:18:33 情報 日付:2025-01-05, 支払金額:3703, お店:X
21:18:33 情報 日付:2023-11-18, 支払金額:565, お店:Y
21:18:35 お知らせ 実行完了
設定以前の支払いが反映されて居ないだけでした。新規に購入した分は反映されており、無事に動作しております。
大変失礼しました。
返信遅れました、失礼しました。
仕様に書いてあるとおり、プログラムそのままですと直近2日分しか反映されないようになっています。
無事動いてよかったです!
お世話になります。
楽天キャッシュを元に支払いをした場合の、楽天Payの履歴をzaimに同期したく、この記事を参照させていただきました。
当方、プログラミングは完全に初心者となります。
動作テストまで実施をし、「実行完了」のLogも出力されているのですが、
zaim側に作成した楽天Payの口座に履歴が反映されないため、ご質問をさせていただきます。
詳細
私は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への書き込みは正常にできていました。エラーメッセージは出てしまいますが、この状態でトリガーの設定をしても大丈夫でしょうか?お手数をお掛けしますがよろしくお願い致します。
情報ありがとうございます。
申し訳ないのですが原因がちょっと分からずでして。
エラーが発生しているのにZaimに登録できるのが分からないですね…
いったん定期実行で運用してみてはいかがでしょうか?
登録できるようであればエラーは無視しても構わない気がします。
こんにちは、zaimに楽天ペイの自動入力化ができないか探していたところ、とても有益な記事を見つけることができ大変感謝しております。
当方プログラム超初心者なのですが、質問がございます。

①>「ZAIM_DB」のスプレッドシートの「支払方法」シートを参照します。
こちらの手順にて支払い方法を参照したところ、自分の銀行口座や楽天ペイの支払いIDはなく、デフォルトらしき「支払方法 お財布、貯金、銀行、…」などが並んでいるのみでした。こちらは正しいのでしょうか?事前に登録した楽天ペイがなく困っております。
② ①に前述した事象がありましたが、いったん仮で支払いIDをその他として入力し、最後まで設定が完了しプログラムを実行しましたが、zaim上に反映されておりません。①での設定が問題かと存じますが、実行ログ上は金額も店舗も正しく読み込めています。

大変有益な情報をありがとうございます。よろしければ、何卒ご指南いただけますと幸いです。
ご質問ありがとうございます。
①ちょっとこれはわからないですが、ユーザがちゃんと認識されているか気になりました。「カテゴリと内訳」シートは正しく取得できているでしょうか?ZAIMに直接問い合わせるのもありかと思います。
②ログを見ると「既に入力済み」と記載されているので恐らく既にZaimに登録されていたりしないでしょうか?このログは同じ支払日、値段、店名がすでにZaimに登録されていると発生します。
ご返信いただきありがとうございます。
①カテゴリと内訳シートは読み込めています。
ただ、Zaimプレミアムに加入しており、その分のカスタマイズされたカテゴリは反映されていないようです。ユーザが認識されていないかもですね・・・。一度Zaimに問い合わせてみようかと思います。
②>既にZaimに登録されていたりしないでしょうか?
既に入力済みとありますが反映されていないのです。。。
もしかしたら①に書いたカテゴリの編集が原因かもしれないので一度デフォルトに戻してみます。
お世話になっております。
とりあえず作り直してみようと最初から手順をやりなおしたところ、無事連携できました。
今まで楽天ペイはデビットカードにしていた時は連携も遅く明細と家計簿がつくのは1週間後だったのですが、こちらはすぐ明細がわかってすごく気持ちがいいです・・・!!この記事を公開してくださって本当にありがとうございました。
最初の手順で詰まった原因についてはわかり次第追記いたします。
無事使えたようでよかったです!
お役に立てて何よりです。
実店舗での決済ではメールで楽天キャッシュとポイント利用が分かれて表示されているのでデータを取り込むことができています。しかし、モバイルオーダーなどのオンライン決済ではそれらが同じ項目で表示されているため、オンライン決済のデータがスキップされてしまうのですが、どこか間違えているのでしょうか?ご教授いただければ幸いです。
ご質問ありがとうございます。
オンライン決済の場合は、最終的なお支払い金額を取得するようになっています。
例えば下記の場合は0円になり、登録しない仕様となっています。
なので結論でいうと現状楽天キャッシュでの支払いは対応できていません。
申し訳ございません。
分かりづらいので仕様に追記しておきます。
質問させてください。
getinfoの実行をしましたが、画像のようなエラーが出ます。
初歩的なところなのかもしれませんが、教えていただけますと助かります。
返信遅れてしまいました。すみません。
ログに表示されているURLはアクセスしてみましたか?
すみません久しぶりにURLにアクセスしたら認証ができました。(以前はエラーが出ていたんですが、、)
その後の設定も問題なく行けました!ありがとうございます。
大変有用なスクリプトをありがとうございます。

スクリプト実行していると下記の画像のようなエラーが出ることがまれにあります。
半年前のコメント欄に同じようなエラーが出ている方がいらっしゃったので、デバッグして原因確認しました。
楽天ペイからのメールの仕様?によるものなのか、bodyにメール本文を取り込んだ際、稀に金額表記が○○円、ではなく、\○○表記となるケースがあり、その際にこのようなエラーがでるようです。(おそらく表記が違うことによりnull値になってエラーが出るものかと…)

そのため、円表記、\表記両方に対応できているようなif文であれば変なエラーが出ることもないかと存じます。
また、1点確認させてください。スクリプトの中で
var max = 2; // 過去いくつまでメールを遡るか
とありますが、一日3件以上楽天payを利用した際でも取り込むことは可能でしょうか?
以上、よろしくお願いいたします。
コメントありがとうございます。
そしてデバッグありがとうございます!
ご指摘事項を踏まえてコードを少し修正しました。
また、ここは過去いくつまでメールを遡るかの件ですがここは定数なので変えられます!
基本的に毎日実行していれば2件だけで十分だったので2にしています!
はじめまして。有益な情報ありがとうございます。

実行すると下記エラーが出ますが原因分かりますでしょうか。
似たような質問してらっしゃる方がいて、その部分を改修されたと思うのですが、原因分からずでした…。
ご質問ありがとうございます。
対応できていたつもりができていないのかもしれません。
こちら以下を実施して共有することは可能でしょうか?
もしかしたら0も取れていない可能性がありますが、、
このような結果でした。
いかがでしょうか。
うーん、ぱっと見問題なさそうですね。
ちょっと気になったのは
下のログに記載されているurlはアクセスしてログインしましたか?
「次のURLを開いて…」以下のところです
URLにアクセスしまして認証されました。
その後再度実行しましたが、やはり同じエラーでした。
デバッグも変わりなしです。
1度キャッシュで支払いをして、Zaimへ転記されるか試みた方がいいでしょうか。
キャッシュで支払いをしたところ、問題なく記録されました。

ログも完了になっていました。
一旦様子見してみます。
すみません、問題が発生するのって楽天カード払いのときでしょうか?
こちら側ではポイント払い、キャッシュ払いの場合は問題ないことは確認できています。
もし、楽天カード払いだけ問題であればもしかしたらそちらだけうまくいっていない可能性があります。(こちらがわでもさらなる調査は可能です)
そのような問題でなければすみません、一旦こちら側で事象が確認できない以上ちょっと原因がわかりかねます。お役に立てず申し訳ございません。
常にキャッシュもしくはポイント払いです。
エラーはポイント払いの時に発生しています。
もしまたなにか分かりましたらご教授頂けると嬉しいです。
こちらでもどこか変な設定してしまっていないかなど確認してみます。