1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カードの引き落とし前に残高不足をスマホに知らせる仕組みを、Gmail と GAS で作った — 銀行は残高をメールで送ってこない

1
Posted at

この記事は Zenn と note にも同じ内容を載せています。Zenn: https://zenn.dev/suisei498/articles/b7a84f9f5c4eb1 / note: https://note.com/suisei498/n/n012df892fb36

クレジットカードの引き落とし日に、口座の残高が足りずに引き落とせなかった。これを二度とやらないために、引き落とし日の前に残高が足りるかを毎朝点検して、足りなければスマホに通知する仕組みを作りました。

材料は Gmail に届く銀行とカード会社のメールだけです。本番は Google Apps Script(GAS)で動いていて、PC の電源とは関係なく毎朝回ります。2026年9月7日から使っています。作るのも直すのも、Claude Code と一緒にやりました。

作ってみると、一番の壁は「残高が分からない」ことでした。ほかにも、自分で誤警報を鳴らしたり、修正が本番に入っていなかったりしたので、その記録も書きます。口座番号や金額は出しません。

全体の流れ

k11_flow.png

  1. 毎朝8〜9時ごろに GAS のトリガーが動く
  2. Gmail から、銀行とカード会社のメールを集める(読むだけ)
  3. 口座ごとに、今の残高と、これからの引き落としを推定する
  4. 引き落としを日付順に消し込んでいって、途中で残高が尽きないかを見る
  5. 足りなければ、スマホに通知する(ntfy という通知サービスを使っています)

残高や手で入れた金額は、スプレッドシートに置いています。スマホからも直せます。

k11_shot_gas.png

銀行は、残高をメールで送ってこない

使っている銀行から届くメールは、次のようなものです。

  • 口座引き落としの事前お知らせ:引き落とされる額(確定額)。ただし、届くのは引き落としの1〜4日前
  • 引き落とし未済のお知らせ:残高不足で引き落とせなかったときの、事後の通知
  • 入金・出金のお知らせ

残高そのものは、どのメールにも書いてありません。そこで、残高はこう推定しています。

実際に確かめた残高(起点)+ その後に届いた入出金メールの積み上げ − もう引き落とされたはずの予定

起点の残高は、スプレッドシートに手で入れます(銀行に公式の API が無いので、家計簿アプリが銀行から取ってきた値を起点に使うこともあります)。起点を取った時刻より後に届いたメールだけを積むようにしたところ、推定が実際の残高と1円まで一致しました。

カード会社のメールも、会社ごとに違う

メールで分かること 困ること
カード会社A 約10日前に予定額(「当月14日時点の予定額」と明記) 確定ではない
カード会社B 使うたびに利用速報 継続課金と ETC が載らない=積み上げは下限にしかならない
カード会社C 請求確定のメール 金額が書いていない。口座振替日だけ

金額は「信頼度」で4種類に分けた

そこで、金額を4種類に分けて持っています。

  • 確定(銀行の事前お知らせ)
  • 予定(カード会社の予定額)
  • 見込み(利用速報の積み上げ。これ以上にはなる、という下限)
  • 金額不明

この仕組みは、「足りない」とは言いますが、「足りる」とは言い切らないようにしています。見込みは下限で、金額不明もあるからです。

判定:合計ではなく、日付順に消し込む

「今月の引き落としの合計 ≦ 残高」で見ると、間違えます。給料の前に引き落としが集中すると、合計では足りていても途中で尽きるからです。

// items: これからの引き落とし [{date, amount}]。amount が null なら金額不明
function findShortfall(balance, items) {
  const sorted = items.slice().sort((a, b) => a.date - b.date);
  let rest = balance;
  for (const it of sorted) {
    if (it.amount == null) return { date: it.date, reason: '金額不明' };
    rest -= it.amount;
    if (rest < 0) return { date: it.date, reason: '不足', short: -rest };
  }
  return null; // 不足が「見つからなかった」だけ。足りるとは言わない
}

実際には、入金の予定も日付順に混ぜて消し込みます。

通知の出し方

k11_notify.png

  • 引き落としの10日前・5日前・前日の3段階で知らせる
  • 引き落とせなかった(未済のお知らせが来た)ときは、最優先で鳴らす
  • 金額不明の引き落としが近づいたら、「金額を入れて」と促す
  • 知らない引き落とし先が出てきたら知らせる
  • 同じ内容は1日1回まで

k11_shot_notify.png

口座は2つあり、片方は引き落としの前に、もう片方から振り替えて入れる運用です。その口座の不足は「振替が必要」という文面にして、振替に必要な額を、振替元の口座の必要額にも足しています。

何も無くても、週に1回は届ける

毎週月曜に、問題が無くても週次のまとめを送ります(低い優先度で)。

通知が来ないとき、「不足が無い」のか「仕組みが止まっている」のか、受け取る側からは区別できません。止まっていることに気づくための、生存確認です。

カード14枚でも、銀行から見えるのは4本だけ

カードは14枚あります。ところが、銀行の引き落としの明細は、カードの発行会社ごとに1行にまとめて来ます。過去2年の事前お知らせ95件を集計すると、引き落とし先の表記は4種類だけでした(ほかに、カードではない定額の自動送金が1種類)。

なので、予定はカード1枚ずつではなく、引き落とし先(発行会社)ごとに立てています。家族カードが何枚ぶら下がっていても、口座から見れば月1回の1本です。

注意点が1つあります。同じ発行会社のカード2枚は、引き落とし先の表記がまったく同じで、明細だけでは見分けられません。引き落とし日の違いと、カード会社のメールに載るカード番号の下桁で、どの口座の分かを振り分けています。

つまずいたこと

1. 事前お知らせが、片方の口座の分だけ届いていなかった

過去2年の事前お知らせ95件を集計したら、2つの口座のうち1つの分が0件でした。通知の対象に、その口座が入っていなかったのです。9月7日に設定して、初めて届いたのは9月28日でした。

2. 入金のお知らせに、金額が書いていなかった

入出金のお知らせで金額まで出すには、「明細表示あり」の詳細設定が要りました。9月7日に設定して、金額が載り始めたのは9月25日に届いた分からです。設定してから反映まで時間差がありました。

3. 自分の口座どうしの振替は、通知されない

自分名義の口座間で振り替えても、入金側にも出金側にも通知が来ません(実際に振り替えて確かめました)。他人への振込も、受付完了の通知に金額がありません(過去1年75件すべて)。振替をしたら、残高を手で直す運用にしています。

一度、他人への振込とその返金を、自分の口座間の振替と取り違えて「振替の入金は通知される」と結論してしまいました。金額の載っていない通知を、時刻だけで取引と結びつけない、が教訓です。

4. 予定額が、引き落とし日を過ぎても残高から引かれていなかった

確定額しか残高から引いていなかったため、手で入れた予定額の引き落としが、日付を過ぎても残高に残っていました。13日間、推定残高が実際より多く(=不足を見逃す向きに)ずれていました。

5. 同じ引き落としを2回数えて、誤警報を鳴らした

k11_shot_log.png

9月28日の朝、実際は足りているのに「振替が必要」と鳴りました(引き落とし額の約84%を振り替えて、という内容)。

推定残高は、その日の引き落としをもう引いた後の値でした。ところが、予定の一覧にも同じ引き落としが残っていて、もう一度引いていました。引き落とし日の当日が、「残高から引く側」と「予定に残す側」の両方に入る境界になっていたのです。

同じ日に手元で再現してみると、もう1つ穴が見つかりました。先に手で入れていた予定に、銀行の確定のお知らせが後から届くと、同じ引き落としが2本立ち、ほぼ2倍の振替を求めます。

k11_double.png

直し方は、①2つの境界を揃える、②確定が来たら、同じ口座・同じ日の手入力と予定額を捨てる、の2つです。

6. 直したはずの修正が、8日間本番に入っていなかった

GAS のエディタへの反映に、クリップボードを使っていました。ところが、同じ PC で並行して動いていた別の作業(別の AI のセッション)が、クリップボードを上書きしていました。

エディタには別の作業の文字列が貼られ、画面は「保存済み」。9月28日の修正と、10月6日朝の追加が、両方とも入っていませんでした。

今は、ファイルを直接ブラウザに読ませて流し込み、保存した後に再読み込みと試運転で中身を確かめるようにしています。

7. メールの読み取りで細かく転んだ

  • カード会社Bの利用速報は、Gmail の検索結果に出る抜粋と、本文(text/plain)で形式が違い、最初の読み取り処理は20件全部失敗した
  • カード会社Cのメールは text/plain が無く HTML だけで、本文が空になって日付が取れなかった
  • Gmail を短時間に読みすぎると 403 になる(1分に約50件)。待ち時間を倍々にして再試行するようにした

まとめ

  • 銀行は残高をメールで送ってこない。確かめた残高を起点に、その後のメールだけを積むと、1円まで合った
  • 金額は確定・予定・見込み・不明に分けて、「足りない」とは言うが「足りる」とは言わない
  • 判定は合計ではなく、日付順に消し込んで途中で尽きないか
  • 通知が来ないことの意味を区別するために、何も無くても週1回は届ける
  • カード14枚でも、銀行から見える引き落としは発行会社ごとの4本。予定はそこで立てる
  • 誤警報の原因は、引き落とし日の当日が両側に入る境界だった。再現すると、確定と手入力の二重計上も見つかった
  • クリップボードは、並行して動く別の作業に上書きされる。反映したら、読み直して確かめる

関連記事(同じ書き手)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?