【Unit4 ブログリレー2日目】
こんにちは、Unit4(エムスリーのサイトプロモーションを行うグループ)でエンジニアをしている井本です。

参考:姜在彦『朝鮮半島史』角川ソフィア文庫 5章
今回は、LINEを使った家計簿の自動化のお話をします。
我が家は家計を分けている共働き夫婦で、家賃や食費などの共用費用は割り勘が基本です。家賃は共用口座から引き落とし、食費もなるべく共用口座に紐づけたクレカで払うようにしています。ただ、カード決済できない店で現金払いしたとか、期限間近のポイントを消化するためにQR決済するケースもあります。
対策として誰がいくら払ったかをスプレッドシートに家計簿としてつけていましたが、スプシを開いて、シートを探して、入力して…が地味に面倒で続かなくなり、記載を後回しにした結果、レシートをなくすこともしばしばありました。
そこで、LINEにメッセージを送るだけで家計簿に記録される仕組みを自作しました。開発時間は1〜2時間ほどです。この記事ではその構成と実装をざっくり紹介します。
構成のポイント
このシステムを作るにあたって意識したのは、開発コストも運用コストもできるだけかけないことです。
- UIはLINE: このシステムのキモです。スプシ家計簿の面倒さの正体は「アプリを開く」という摩擦でした。LINEであればスマホのホーム画面の開きやすい位置に鎮座していることが多く、買い物のついでにサッと送れます。専用アプリを作る必要もありません
- DBはスプレッドシート: データの書き込み先がそのまま閲覧・集計UIになる。DBインスタンスの実行コストもゼロ
- ロジックはGAS: サーバーを立てなくていい。無料枠で動く
集計ロジック(月ごとの合計、差額の計算など)はスプレッドシートの数式に任せています。アプリ側に計算処理を実装する必要がなく、シンプルに保てます。
アーキテクチャ
LINEボット(UI) ↓ テキスト入力(例:「スーパー 3000」) LINE Messaging API ↓ Webhook POST GAS(Google Apps Script) ↓ テキストパース → スプレッドシートに書き込み Google スプレッドシート(DB兼集計シート)
LINEボットにメッセージを送ると、LINE Messaging APIがGASのエンドポイントにPOSTします。GASがそのテキストをパースして、スプレッドシートの所定の位置に書き込むシンプルなアーキテクチャです。
LINE Messaging APIの設定
まず LINE Developers コンソールでチャネルを作成します。
- LINE Developers にログインし、プロバイダーを作成
- 「Messaging API」チャネルを作成
次にGASをWebアプリとしてデプロイします。
- スクリプトエディタで「デプロイ」横のプルダウンから「新しいデプロイ」を選択
- 種類として「ウェブアプリ」を選択し、アクセスできるユーザーを「全員」に設定
- 発行されたURLをコピー
そのURLをLINE Developersコンソールの「Messaging API設定」→「Webhook URL」に登録し、「Webhookの利用」をオンにします。「検証」ボタンで疎通確認し、GAS側が200を返せばOKです。
GASの実装
Webhookの受け取り
GASはHTTP POSTを doPost(e) 関数で受け取ります。
function doPost(e) { const event = JSON.parse(e.postData.contents).events[0]; const userId = event.source.userId; const text = event.message.text; saveExpense(userId, text); return ContentService.createTextOutput('OK'); }
テキストのパース
入力フォーマットは「品目、金額」です。
スーパー、3200 外食、4800

function parseExpense(text) { const [what, amount] = text.split(/[、,\s]+/); return { what, howMuch: Number(amount) }; }
セパレータは読点・カンマ・スペースを受け付けています。家族で入力のクセがバラバラなので複数定義しています。
スプレッドシートへの書き込み
誰が送ったかはuserIdで識別します。userIdはスプレッドシートにそのまま記録しており、スプシ側でuserIdと名前を紐づけるようにしています。
userIdの確認は、事前に doPost 内で Logger.log(userId) を仕込んでLINEからメッセージを送り、GASのログで確認しました。
function saveExpense(userId, text) { const { what, howMuch } = parseExpense(text); const sh = SpreadsheetApp.openById('スプレッドシートのID').getSheetByName('シート名'); const r = sh.getLastRow() + 1; sh.getRange(r, 1).setValue(new Date()); sh.getRange(r, 2).setValue(what); sh.getRange(r, 3).setValue(userId); sh.getRange(r, 4).setValue(howMuch); }
書き込まれたデータは次のような形になります。
| 日時 | 品目 | userId | 金額 |
|---|---|---|---|
| 2026/07/24 | スーパー | Uxxxxxxx... | 3200 |
| 2026/07/24 | 外食 | Uyyyyyyy... | 4800 |
集計(月ごとの合計、差額など)はスプレッドシートの数式で別シートに自動反映されるようにしています。この部分はアプリ側では何もしていません。
運用としては、ふたりの支払総額の差を見て、どちらかが払いすぎていないかをざっくり確認する程度です。毎月きっちり精算するのも面倒なので、大きめの支払いが発生したときに少ない方が払う、という形でバランスを取っています。
運用ハック
運用する中で見つけた便利な使い方をいくつか紹介します。
誤入力の取り消し
誤って入力してしまった場合は、マイナス金額で取り消しエントリを送ります。品目名に「取り消し」を添えることで証跡として残るようにしています。
電球取り消し、-391
※ 実際の入力例
スプシ側で合計を取っているだけなので、マイナスで相殺される仕組みです。
スプレッドシートの数式に計算を任せる
スプレッドシートはセルに = から始まる文字列を入力すると数式として評価します。これを逆手にとって、LINEから計算式ごと送ると、スプシ側で計算した結果が記録されます。
レシートに自分用の買い物と共用の買い物が混ざっているケースなどで便利です。
スーパー、=3200-800
※ 実際の入力例(3200円の買い物のうち800円が自分用だった場合)
なお、これはいわゆる関数インジェクションです。LINE botのアクセス制御により家族のみが利用可能で、外部からの入力を受け付けないため悪用の心配はなく、むしろ便利な機能として意図的に残しています。
まとめ
個人向けのちょっとしたツールを作ろうとすると、Webサーバーを立てれば維持費がかかり、アプリとして公開しようとすれば開発者登録費用がかかります。LINE + GAS + スプレッドシートの構成ならその心配がありません。
| 項目 | 構成 | コスト |
|---|---|---|
| UI | LINE | 無料 |
| ロジック | Google Apps Script | 無料(無料枠内) |
| DB | Google スプレッドシート | 無料 |
| サーバー | なし | ゼロ |
月々の維持費ゼロ、サーバー管理不要、専用アプリの開発不要。LINEとスプレッドシートというすでに使い慣れたツールを組み合わせることで、最小限の実装で家計管理の手間を大幅に削減できました。
「ちゃんとしたアプリを作る」のではなく、「面倒を解消する」にフォーカスした結果、ちょうどいい落とし所に収まったと思っています。
また、このアーキテクチャのいいところは拡張しやすい点です。入力テキストのパース結果で処理を分岐すれば、同じボットに機能を追加できます。最近は家族の予定を共有カレンダーに追加する機能も組み込みました。8/1、焼肉 のように送ると Google カレンダーに登録される仕組みで、家計簿と同じ感覚でLINEから使えます。
似たような悩みを抱えている方はぜひ試してみてください。
We are hiring!
エムスリーではエンジニアを絶賛募集中です! エムスリーでのプロダクト開発に興味がある方、ぜひカジュアル面談にご応募ください!