背景:PayPay 利用明細 CSV を Money Forward ME へ手入力する負担が大きい。
目的:PayPay 利用明細 CSV の読み取り、仕訳ルール適用、Money Forward ME への登録を自動化し、登録に要する時間を短縮する。
- PayPay 利用明細 CSV を読み込み、取引データを解析する。
- 取引番号プレフィックス除外とカテゴリマッピングを設定ファイルで制御できる。
- 同じルール配列で、カテゴリ登録と振替登録の両方を制御できる。
- 特定の入金は固定業務ルールに基づき、Money Forward 登録日を 30 日後へ補正する。
- Playwright の persistent profile により、初回ログイン後は再ログインなしで実行できる。
- dry-run モードで登録前に件数確認のみ実行できる。
- 日付入力後は保存前に datepicker のクローズを試み、UI 重なりによる保存失敗リスクを下げる。
- 登録失敗時にスクリーンショットを保存できる。
| 引数 | 必須 | 説明 |
|---|---|---|
--csv=<path> |
必須 | PayPay 利用明細 CSV ファイルパス |
--config=<path> |
任意 | 設定 JSON ファイルパス(既定値: config.json) |
| --headless | 任意 | Edge をヘッドレスモードで起動する |
| --dry-run | 任意 | 解析とフィルタのみ実行し、MF へ登録しない |
| --keep-open | 任意 | 終了時にブラウザーを閉じず Enter を待つ(headed 時のみ) |
補足:--csv が未指定の場合は終了コード 1 を返す。
| 項目 | 内容 |
|---|---|
| テンプレート | config_sample.json |
| ユーザー設定ファイル名 | config.json(任意のパス指定も可) |
| 形式 | JSON |
| エンコーディング | UTF-8 / UTF-8 BOM |
設定項目:
| キー名 | データ型 | 説明 |
|---|---|---|
| mfAccount | string | Money Forward 側の対象口座名 |
| excludePrefixes | string[] | 取引番号プレフィックス一致で除外 |
| mappingRules | object[] | 取引先キーワードによるカテゴリ割り当て、または振替登録ルール |
| categoryMap | object | 中カテゴリ名 -> 大カテゴリ名の対応 |
| duplicateDetection.backend | string | local または gcloud |
| duplicateDetection.databaseId | string | Firestore DB ID(gcloud 使用時。既定値 (default)) |
| duplicateDetection.localStorePath | string | local バックエンドの履歴 JSON パス。相対パスは config.json のあるディレクトリ基準(既定値 logs/processed.json) |
| gcloudCredentialsPath | string | gcloud サービスアカウント JSON パス(gcloud 使用時に必須)。相対パスは config.json のあるディレクトリ基準 |
| advanced.screenshotOnError | boolean | 登録失敗時にスクリーンショット保存 |
| advanced.includeUiCloseDiagnosticsOnError | boolean | 登録失敗時に datepicker クローズ処理の診断情報を追加出力(既定値: false) |
mappingRules のスキーマ:
| キー名 | データ型 | 必須 | 説明 |
|---|---|---|---|
| keyword | string | 必須 | 取引先 に対する照合文字列 |
| matchMode | string | 任意 | contains、starts_with、regex。既定値は contains |
| direction | string | 任意 | expense、income、any。既定値は any |
| priority | number | 任意 | 数値が大きいルールを優先 |
| category | string | 条件付き | 通常のカテゴリ登録ルールで使う中カテゴリ名 |
| isTransfer | boolean | 条件付き | true の場合はカテゴリ登録ではなく振替登録として扱う |
| transferAccount | string | 条件付き | 振替相手の口座名。isTransfer=true の場合に必須 |
補足:
categoryとisTransfer=trueは同時指定しない。categoryを指定したルールは、通常の入出金カテゴリ登録として扱う。isTransfer=trueのルールは、カテゴリ登録ではなく振替登録として扱う。- 同一取引に複数ルールが一致した場合は、
priorityの高い順で評価する。 priorityが同じ場合は、mappingRulesの記述順(上から)を優先する。direction=expenseの振替ルールは、PayPay を振替元、transferAccountを振替先として登録する。direction=incomeの振替ルールは、transferAccountを振替元、PayPay を振替先として登録する。
duplicateDetection.localStorePath と gcloudCredentialsPath に相対パスを
指定した場合、その解決基準は config.json のあるディレクトリです。
例えば、config.json が /workspace/config.json の場合:
logs/processed.json→/workspace/logs/processed.json./secrets/paypay2mf-credentials.json→/workspace/secrets/paypay2mf-credentials.json/tmp/processed.json(絶対パス) →/tmp/processed.json(そのまま使用)
{
"mfAccount": "PayPay",
"excludePrefixes": ["PPCD_A_"],
"mappingRules": [
{
"keyword": "Seven",
"category": "Food",
"matchMode": "contains",
"direction": "expense",
"priority": 100
},
{
"keyword": "PayPayポイント運用",
"isTransfer": true,
"transferAccount": "PayPayポイント",
"matchMode": "contains",
"direction": "expense",
"priority": 400
}
],
"categoryMap": {
"Food": "Living"
},
"duplicateDetection": {
"backend": "local",
"databaseId": "(default)",
"localStorePath": "logs/processed.json"
},
"gcloudCredentialsPath": "./secrets/paypay2mf-credentials.json",
"advanced": {
"screenshotOnError": true,
"includeUiCloseDiagnosticsOnError": false
}
}| 項目 | 内容 |
|---|---|
| 形式 | CSV |
| エンコーディング | UTF-8 / UTF-8 BOM |
| ヘッダー | 必須 |
主要列:
| 列名 | 説明 |
|---|---|
| 取引日 | 日時(yyyy/MM/dd HH:mm:ss) |
| 取引先 | メモ生成とルール判定に使用 |
| 出金金額(円) | 支出金額 |
| 入金金額(円) | 収入金額 |
| 取引内容 | 取引内容テキスト |
| 取引番号 | 除外判定に使用 |
| 取引方法 | 重複判定の入力項目 |
| 支払い区分 | 重複判定の入力項目 |
| 利用者 | 重複判定の入力項目 |
| 海外出金金額 | メモ補足情報 |
| 通貨 | メモ補足情報 |
通常実行時は、登録結果サマリーを標準出力へ表示する。
- 成功: 登録成功件数
- 失敗: 登録失敗件数
- スキップ: 除外などでスキップされた件数
- 除外: プレフィックス除外件数
- 重複: 重複検知でスキップした件数
- 解析失敗: CSV 解析失敗件数
dry-run 時は、以下の集計のみを表示する。
- 合計
- 解析失敗
- 除外
- 重複
- 対象
| パス | 説明 |
|---|---|
| .paypay2mf-profile/ | Playwright persistent profile(ログインセッション保持) |
| artifacts/ | 登録失敗時のスクリーンショット保存先 |
| logs/processed.json | local バックエンドの重複履歴(row_fingerprints 配列) |
npm ci
npx playwright install- 初回は --headless を付けずに実行する。
- ブラウザーが .paypay2mf-profile を使って起動する。
- 表示されたブラウザーで Money Forward に手動ログインする。
- 家計簿画面が表示されたら、ターミナルで Enter を押す。
- 2 回目以降は保存済みプロファイルを再利用し、ログインをスキップする。
補足:初回を --headless で実行すると手動ログインできないため、エラーで終了する。
node src/import-paypay-to-mfme.js --csv="C:\\path\\paypay.csv"
node src/import-paypay-to-mfme.js --csv="C:\\path\\paypay.csv" --dry-run
node src/import-paypay-to-mfme.js --csv="C:\\path\\paypay.csv" --headless
node src/import-paypay-to-mfme.js --csv="C:\\path\\paypay.csv" --config="C:\\path\\config.json"
npm run smoke:dry-run| 項目 | 内容 |
|---|---|
| OS | Windows 10 / Windows 11 |
| Node.js | 24 以上 |
| ブラウザー | Microsoft Edge(stable、最新版推奨) |
| ライブラリー | playwright 1.59.1 以上、@google-cloud/firestore 8.5.0 以上 |
- コマンドライン引数を解析する。
- 設定 JSON と UI セレクター設定を読み込む。
- PayPay 利用明細 CSV を読み込み、行単位で解析して取引データを生成する。
- 次の条件の全てに当てはまる特定の入金だけ、登録用日付を 30 日後へ補正する。
条件:
取引内容=ポイント、残高の獲得かつ取引方法=PayPayポイントかつ取引先がワイモバイルとYahoo!ズバトク以外。 - ルールに基づきカテゴリを付与し、プレフィックス除外と重複検知を適用する。
- 振替ルールに一致した取引は、カテゴリの代わりに振替元・振替先を決定する。
- dry-run 指定時は集計のみ出力して終了する(履歴更新なし)。
- ブラウザーを起動し、必要に応じてログイン完了を待つ。
- 対象取引を 1 件ずつ Money Forward 手入力画面へ登録する。
- 通常ルールは口座とカテゴリを入力し、振替ルールは同一モーダルの振替タブで振替元・振替先を入力する。
- 日付入力後は datepicker が残っている場合に備えて、保存前にクローズを試みる。
- 登録成功後に重複履歴を更新する。
- 実行サマリーを出力し、ブラウザーコンテキストを終了する。
flowchart TD
A[引数解析] --> B[設定ファイル読込]
B --> C[CSV読込と解析]
C --> D[対象入金の日付補正]
D --> E[ルール適用と除外処理]
E --> F{dry-run?}
F -->|Yes| G[集計を表示して終了]
F -->|No| H[Edge起動とログイン確認]
H --> I[取引を1件ずつ登録]
I --> J[成功/失敗件数を集計]
J --> K[サマリー出力して終了]
補足:
- 重複指紋は PayPay 利用明細 CSV の
取引日を使って判定し、補正後日付へは切り替えない。
| 項目 | 内容 |
|---|---|
| 出力先 | 標準出力 / 標準エラー |
| 形式 | プレーンテキスト |
ドライランモード
合計=120
解析失敗=2
除外=15
重複=7
対象=96
成功=100
失敗=3
スキップ=24
除外=15
重複=9
解析失敗=2
[登録失敗] 行=23 取引先=Example Store エラー=Money Forwardの口座選択に指定口座が見つかりません: PayPay
[成果物] スクリーンショット=C:\path\to\artifacts\failed-row-23-XXXXXXXX.png
[UI診断] 行=23 closeSteps={"blurInput":{"ok":true,"error":null},"pressTab":{"ok":false,"error":"press failed"},"clickModalSafeArea":{"ok":true,"error":null},"waitDatepickerHidden":{"ok":false,"error":"wait failed"}}
補足:
[UI診断]はadvanced.includeUiCloseDiagnosticsOnError=trueかつ datepicker クローズ手順で失敗が発生した場合のみ出力される。
MIT License
| ライブラリー名 | バージョン | ライセンス |
|---|---|---|
| playwright | 1.55.0 以上 | Apache-2.0 |
| @google-cloud/firestore | 8.5.0 以上 | Apache-2.0 |
| 項目 | 内容 |
|---|---|
| OS | Microsoft Windows 11 Home 10.0.26200 |
| ランタイム | Node.js v24.12.0 |
| 自動化基盤 | Playwright 1.59.1 |
| 対象ブラウザー | Microsoft Edge 147.0.3912.98 |
| エディター | Visual Studio Code 1.119.0 |
| ファイル | 説明 |
|---|---|
| src/import-paypay-to-mfme.js | CLI エントリポイント(起動・画面操作・実行制御) |
| src/import-core.js | CSV解析・変換・フィルタなどの純粋ロジック |
| src/duplicate-detector.js | 重複検知(local / gcloud バックエンド) |
| src/mfme.config.json | Money Forward UI セレクター・タイムアウト設定 |
| config_sample.json | ユーザー設定サンプル |
npm ci
npm test
npm run lint:md
npm run compare:fingerprint:python
npm run test:gcloud:e2e
npm run smoke:dry-run| バージョン | 日付 | 内容 |
|---|---|---|
| 1.1.1 | 2026-05-31 | バグ修正: 振替保存時に datepicker が残留してクリックを遮断し、登録がタイムアウトする |
| 1.1.0 | 2026-05-10 | 振替も自動登録できる機能を追加 Node.js 24 対応 |
| 1.0.0 | 2026-05-06 | 初版作成 |