Skip to content

支出の抽出と PostgreSQL 保存

関連: Bot 開発 / PostgreSQL

何が増えたか

Discord / DM のメッセージを Gemini が解釈して:

  1. 支出なら expenses テーブルに保存
  2. 関西弁の reply を返す
  3. 雑談なら保存せず返事だけ

テーブル

定義は sql/001004。Bot 起動時に順に自動適用される。

主な列:

意味
amount_yen 金額(円)
merchant 店名など
category 大分類taxonomy.py の固定リスト)。不明は「その他」
subcategories 小分類配列(同じファイルの固定リスト)。一覧外は捨てる
occasion 場面(朝食/昼食/…)。不明なら null
occasion_reason 場面推定の短い根拠
line_items レシート内訳(JSONB)。読めなければ null
raw_text 元メッセージ(画像のみは [image]
paid_at 利用日時(分かれば)

大分類・小分類(固定)

定義は src/finance_manager/taxonomy.py

  • 大分類 (category): 食費 / 日用品 / 交通 / 娯楽 / 光熱費 / 通信 / 医療 / 衣服 / 教育 / その他
  • 小分類 (subcategories): コンビニ / カフェ / 遊び / 映画 / サブスク / 旅行 / …(最大5)

増やすときはそのファイルを編集する。

複数件の記録

1メッセージに複数の支出を書ける。

例: スタバ680とセブン320

expenses 配列として複数 INSERT。返事に id=…, … が並ぶ。

事前確認

.env に DB 接続があること:

DATABASE_URL=postgresql://finance_app:PASSWORD@127.0.0.1:5432/finance_manager

依存関係を更新:

cd ~/finance-manager
source .venv/bin/activate
pip install -r requirements.txt

試し方

  1. Bot を起動
  2. DM か指定チャンネルで送る
  3. テキスト例: スタバで680円 食費
  4. 画像例: レシート写真のみ、または「これ記録して」+ スクショ
  5. 返事に DBに保存したで。id=... が付けば成功
    (場面・内訳が取れたときは 場面=夕食 / 内訳N件 も付く)
  6. DB で確認:
psql -h 127.0.0.1 -U finance_app -d finance_manager -c \
  "SELECT id, amount_yen, merchant, category, subcategories, occasion, line_items, created_at
   FROM expenses ORDER BY id DESC LIMIT 5;"

ガードレール

  • テキストのみ: Gemini が抜いた金額が本文の数字に含まれていなければ保存しない
  • 画像あり: 金額は画像 OCR 由来なので、本文に数字が無くても保存可(捏造禁止はプロンプト側)
  • is_expense=true でも金額が不正なら雑談扱い
  • 内訳は画像で明細が読めるときだけ。見えなければ空